From 7f4a60f03315dfe2968ce131249bba930dc762cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johel=20Ernesto=20Guerrero=20Pe=C3=B1a?= Date: Thu, 14 Dec 2023 17:27:27 -0400 Subject: [PATCH] fix(sema): do not stack an implicit else branch --- regression-tests/pure2-last-use.cpp2 | 14 ++++++++ .../test-results/pure2-last-use.cpp | 32 +++++++++++++++---- source/reflect.h | 28 ++++++++-------- source/reflect.h2 | 2 +- source/sema.h | 21 ++++++------ 5 files changed, 67 insertions(+), 30 deletions(-) diff --git a/regression-tests/pure2-last-use.cpp2 b/regression-tests/pure2-last-use.cpp2 index 4dd7e8306..517209c14 100644 --- a/regression-tests/pure2-last-use.cpp2 +++ b/regression-tests/pure2-last-use.cpp2 @@ -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) = { diff --git a/regression-tests/test-results/pure2-last-use.cpp b/regression-tests/test-results/pure2-last-use.cpp index 1263c1f77..478e3c6d5 100644 --- a/regression-tests/test-results/pure2-last-use.cpp +++ b/regression-tests/test-results/pure2-last-use.cpp @@ -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; @@ -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; @@ -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 { @@ -386,17 +392,31 @@ auto draw() -> void{ static_cast(CPP2_UFCS_MOVE(vertex)((std::move(pos)))); } -#line 178 "pure2-last-use.cpp2" +auto enum_0() -> void{ + cpp2::deferred_init underlying_type; + if (true) {} + underlying_type.construct(0); +} + +auto enum_1() -> void{ + cpp2::deferred_init 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(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>()); } diff --git a/source/reflect.h b/source/reflect.h index afc4afacb..4f5090b44 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -1360,7 +1360,7 @@ auto basic_enum( std::vector enumerators {}; cpp2::i64 min_value {}; cpp2::i64 max_value {}; - std::string underlying_type {}; + cpp2::deferred_init underlying_type; CPP2_UFCS(reserve_names)(t, "operator=", "operator<=>"); if (bitwise) { @@ -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}; { @@ -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::min()) && cpp2::cmp_less_eq(max_value,std::numeric_limits::max())) { - underlying_type = "i8"; + underlying_type.value() = "i8"; } else {if (cpp2::cmp_greater_eq(min_value,std::numeric_limits::min()) && cpp2::cmp_less_eq(max_value,std::numeric_limits::max())) { - underlying_type = "i16"; + underlying_type.value() = "i16"; } else {if (cpp2::cmp_greater_eq(min_value,std::numeric_limits::min()) && cpp2::cmp_less_eq(max_value,std::numeric_limits::max())) { - underlying_type = "i32"; + underlying_type.value() = "i32"; } else {if (cpp2::cmp_greater_eq(std::move(min_value),std::numeric_limits::min()) && cpp2::cmp_less_eq(std::move(max_value),std::numeric_limits::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)"); @@ -1440,16 +1440,16 @@ std::string value = "-1"; else { auto umax {std::move(max_value) * cpp2::as_()}; if (cpp2::cmp_less_eq(umax,std::numeric_limits::max())) { - underlying_type = "u8"; + underlying_type.value() = "u8"; } else {if (cpp2::cmp_less_eq(umax,std::numeric_limits::max())) { - underlying_type = "u16"; + underlying_type.value() = "u16"; } else {if (cpp2::cmp_less_eq(std::move(umax),std::numeric_limits::max())) { - underlying_type = "u32"; + underlying_type.value() = "u32"; } else { - underlying_type = "u64"; + underlying_type.value() = "u64"; }}} } } @@ -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;"); diff --git a/source/reflect.h2 b/source/reflect.h2 index 66e21f2f8..a0843f334 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -859,7 +859,7 @@ basic_enum: ( enumerators : std::vector = (); min_value : i64 = (); max_value : i64 = (); - underlying_type : std::string = (); + underlying_type : std::string; t.reserve_names( "operator=", "operator<=>" ); if bitwise { diff --git a/source/sema.h b/source/sema.h index 35f0e70fc..0c6444daa 100644 --- a/source/sema.h +++ b/source/sema.h @@ -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, @@ -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 @@ -1079,7 +1073,11 @@ class sema auto const& sym = std::get(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 ( @@ -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;