Skip to content

Commit

Permalink
fix(sema): do not stack an implicit else branch
Browse files Browse the repository at this point in the history
  • Loading branch information
JohelEGP committed Dec 14, 2023
1 parent 7d72130 commit 7f4a60f
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 30 deletions.
14 changes: 14 additions & 0 deletions regression-tests/pure2-last-use.cpp2
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,20 @@ draw: () = {
_ = (pos).vertex();
}

enum_0: () = {
underlying_type: int;
if true { }
underlying_type = 0;
}

enum_1: () = {
underlying_type: int;
if true {
underlying_type = 0;
}
underlying_type = 0;
}

union: type = {
destroy: (inout this) = { }
operator=: (move this) = {
Expand Down
32 changes: 26 additions & 6 deletions regression-tests/test-results/pure2-last-use.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ class issue_857_3;
class issue_869;


#line 177 "pure2-last-use.cpp2"
#line 191 "pure2-last-use.cpp2"
class cpp2_union;


#line 185 "pure2-last-use.cpp2"
#line 199 "pure2-last-use.cpp2"
class my_string;


Expand Down Expand Up @@ -168,6 +168,12 @@ auto issue_888(std::string r, int size) -> void;
auto draw() -> void;

#line 177 "pure2-last-use.cpp2"
auto enum_0() -> void;

#line 183 "pure2-last-use.cpp2"
auto enum_1() -> void;

#line 191 "pure2-last-use.cpp2"
class cpp2_union {
public: auto destroy() & -> void;
public: ~cpp2_union() noexcept;
Expand All @@ -176,7 +182,7 @@ class cpp2_union {
public: auto operator=(cpp2_union const&) -> void = delete;


#line 183 "pure2-last-use.cpp2"
#line 197 "pure2-last-use.cpp2"
};

class my_string {
Expand Down Expand Up @@ -386,17 +392,31 @@ auto draw() -> void{
static_cast<void>(CPP2_UFCS_MOVE(vertex)((std::move(pos))));
}

#line 178 "pure2-last-use.cpp2"
auto enum_0() -> void{
cpp2::deferred_init<int> underlying_type;
if (true) {}
underlying_type.construct(0);
}

auto enum_1() -> void{
cpp2::deferred_init<int> underlying_type;
if (true) {
underlying_type.construct(0);
}
underlying_type.construct(0);
}

#line 192 "pure2-last-use.cpp2"
auto cpp2_union::destroy() & -> void{}
cpp2_union::~cpp2_union() noexcept{
destroy();
static_cast<void>(std::move((*this)));
}

#line 190 "pure2-last-use.cpp2"
#line 204 "pure2-last-use.cpp2"
auto main(int const argc_, char** argv_) -> int{
auto const args = cpp2::make_args(argc_, argv_);
#line 191 "pure2-last-use.cpp2"
#line 205 "pure2-last-use.cpp2"
issue_683(args);
issue_847_2(std::vector<std::unique_ptr<int>>());
}
Expand Down
28 changes: 14 additions & 14 deletions source/reflect.h
Original file line number Diff line number Diff line change
Expand Up @@ -1360,7 +1360,7 @@ auto basic_enum(
std::vector<value_member_info> enumerators {};
cpp2::i64 min_value {};
cpp2::i64 max_value {};
std::string underlying_type {};
cpp2::deferred_init<std::string> underlying_type;

CPP2_UFCS(reserve_names)(t, "operator=", "operator<=>");
if (bitwise) {
Expand All @@ -1369,7 +1369,7 @@ auto basic_enum(

// 1. Gather: The names of all the user-written members, and find/compute the type

underlying_type = CPP2_UFCS(get_argument)(t, 0);// use the first template argument, if there was one
underlying_type.construct(CPP2_UFCS(get_argument)(t, 0));// use the first template argument, if there was one

auto found_non_numeric {false};
{
Expand Down Expand Up @@ -1415,23 +1415,23 @@ std::string value = "-1";

// Compute the default underlying type, if it wasn't explicitly specified
#line 913 "reflect.h2"
if (underlying_type == "")
if (underlying_type.value() == "")
{
CPP2_UFCS(require)(t, !(std::move(found_non_numeric)),
"if you write an enumerator with a non-numeric-literal value, you must specify the enumeration's underlying type");

if (!(bitwise)) {
if (cpp2::cmp_greater_eq(min_value,std::numeric_limits<cpp2::i8>::min()) && cpp2::cmp_less_eq(max_value,std::numeric_limits<cpp2::i8>::max())) {
underlying_type = "i8";
underlying_type.value() = "i8";
}
else {if (cpp2::cmp_greater_eq(min_value,std::numeric_limits<cpp2::i16>::min()) && cpp2::cmp_less_eq(max_value,std::numeric_limits<cpp2::i16>::max())) {
underlying_type = "i16";
underlying_type.value() = "i16";
}
else {if (cpp2::cmp_greater_eq(min_value,std::numeric_limits<cpp2::i32>::min()) && cpp2::cmp_less_eq(max_value,std::numeric_limits<cpp2::i32>::max())) {
underlying_type = "i32";
underlying_type.value() = "i32";
}
else {if (cpp2::cmp_greater_eq(std::move(min_value),std::numeric_limits<cpp2::i64>::min()) && cpp2::cmp_less_eq(std::move(max_value),std::numeric_limits<cpp2::i64>::max())) {
underlying_type = "i64";
underlying_type.value() = "i64";
}
else {
CPP2_UFCS(error)(t, "values are outside the range representable by the largest supported underlying signed type (i64)");
Expand All @@ -1440,16 +1440,16 @@ std::string value = "-1";
else {
auto umax {std::move(max_value) * cpp2::as_<cpp2::u64, 2>()};
if (cpp2::cmp_less_eq(umax,std::numeric_limits<cpp2::u8>::max())) {
underlying_type = "u8";
underlying_type.value() = "u8";
}
else {if (cpp2::cmp_less_eq(umax,std::numeric_limits<cpp2::u16>::max())) {
underlying_type = "u16";
underlying_type.value() = "u16";
}
else {if (cpp2::cmp_less_eq(std::move(umax),std::numeric_limits<cpp2::u32>::max())) {
underlying_type = "u32";
underlying_type.value() = "u32";
}
else {
underlying_type = "u64";
underlying_type.value() = "u64";
}}}
}
}
Expand All @@ -1462,9 +1462,9 @@ std::string value = "-1";
CPP2_UFCS(remove_marked_members)(t);

// Generate all the common material: value and common functions
CPP2_UFCS(add_member)(t, " _value : " + cpp2::to_string(underlying_type) + ";");
CPP2_UFCS(add_member)(t, " private operator= : (implicit out this, _val: i64) == _value = cpp2::unsafe_narrow<" + cpp2::to_string(underlying_type) + ">(_val);");
CPP2_UFCS(add_member)(t, " get_raw_value : (this) -> " + cpp2::to_string(std::move(underlying_type)) + " == _value;");
CPP2_UFCS(add_member)(t, " _value : " + cpp2::to_string(underlying_type.value()) + ";");
CPP2_UFCS(add_member)(t, " private operator= : (implicit out this, _val: i64) == _value = cpp2::unsafe_narrow<" + cpp2::to_string(underlying_type.value()) + ">(_val);");
CPP2_UFCS(add_member)(t, " get_raw_value : (this) -> " + cpp2::to_string(std::move(underlying_type.value())) + " == _value;");
CPP2_UFCS(add_member)(t, " operator= : (out this, that) == { }");
CPP2_UFCS(add_member)(t, " operator<=> : (this, that) -> std::strong_ordering;");

Expand Down
2 changes: 1 addition & 1 deletion source/reflect.h2
Original file line number Diff line number Diff line change
Expand Up @@ -859,7 +859,7 @@ basic_enum: (
enumerators : std::vector<value_member_info> = ();
min_value : i64 = ();
max_value : i64 = ();
underlying_type : std::string = ();
underlying_type : std::string;

t.reserve_names( "operator=", "operator<=>" );
if bitwise {
Expand Down
21 changes: 12 additions & 9 deletions source/sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ struct selection_sym {
struct compound_sym {
bool start = false;
compound_statement_node const* compound = {};
enum kind { is_scope, is_true, is_false } kind_ = is_scope;
enum kind { is_scope, is_implicit_scope, is_true, is_false } kind_ = is_scope;

compound_sym(
bool s,
Expand Down Expand Up @@ -848,13 +848,7 @@ class sema
return true;
}

// If this is a member variable in a constructor, the name doesn't
// appear lexically right in the constructor, so prepending "this."
// to the printed name might make the error more readable to the programmer
auto name = decl->identifier->to_string();
if (decl->declaration->parent_is_type()) {
name += " (aka this." + name + ")";
}

struct stack_entry{
int pos; // start of this selection statement
Expand Down Expand Up @@ -1079,7 +1073,11 @@ class sema
auto const& sym = std::get<symbol::active::compound>(symbols[pos].sym);

// If we're in a selection
if (std::ssize(selection_stack) > 0) {
if (
std::ssize(selection_stack) > 0
&& sym.kind_ != compound_sym::kind::is_implicit_scope
)
{
// If this is a compound start with the current selection's depth
// plus one, it's the start of one of the branches of that selection
if (
Expand Down Expand Up @@ -1995,7 +1993,12 @@ class sema
&& active_selections.back()->false_branch.get() == &n
)
{
kind = compound_sym::is_false;
if (active_selections.back()->has_source_false_branch) {
kind = compound_sym::is_false;
}
else {
kind = compound_sym::is_implicit_scope;
}
}
}
return kind;
Expand Down

0 comments on commit 7f4a60f

Please sign in to comment.