On Thu, Feb 27, 2025 at 01:15:12PM -0500, Jason Merrill wrote: > On 2/20/25 9:51 AM, Marek Polacek wrote: > > Now with the test fixed. > > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? > > > > -- >8 -- > > In this PR we crash in cxx_eval_constant_expression/GOTO_EXPR on: > > > > gcc_assert (cxx_dialect >= cxx23); > > > > The code obviously doesn't expect to see a goto pre-C++23. But we can > > get here with the new prvalue optimization. In this test we found > > ourselves in synthesize_method for X::X(). This function calls: > > > > a) finish_function, which does cp_genericize -> ... -> genericize_c_loops, > > which creates the GOTO_EXPR; > > b) expand_or_defer_fn -> maybe_clone_body -> ... -> cp_fold_function > > where we reach the new maybe_constant_init call and crash on the > > goto. > > Hmm, this looks like bad recursion; finish_function wants to fold before > genericize, but then beacuse maybe_clone_body calls finish_function, we end > up folding again after genericize. > > Maybe we should call maybe_clone_body directly from finish_function rather > than from expand_or_defer?
Probably best to leave that to 16; I wonder what kind of trouble that would unravel. > But the patch is OK as is. Thanks. > > Since we can validly get to that assert, I think we should just remove > > it. I don't see other similar asserts like this one. > > > > PR c++/118928 > > > > gcc/cp/ChangeLog: > > > > * constexpr.cc (cxx_eval_constant_expression) <case GOTO_EXPR>: Remove > > an assert. > > > > gcc/testsuite/ChangeLog: > > > > * g++.dg/cpp0x/constexpr-prvalue5.C: New test. > > --- > > gcc/cp/constexpr.cc | 1 - > > .../g++.dg/cpp0x/constexpr-prvalue5.C | 24 +++++++++++++++++++ > > 2 files changed, 24 insertions(+), 1 deletion(-) > > create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-prvalue5.C > > > > diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc > > index 59dd0668af3..c68666cc5dd 100644 > > --- a/gcc/cp/constexpr.cc > > +++ b/gcc/cp/constexpr.cc > > @@ -8691,7 +8691,6 @@ cxx_eval_constant_expression (const constexpr_ctx > > *ctx, tree t, > > *jump_target = TREE_OPERAND (t, 0); > > else > > { > > - gcc_assert (cxx_dialect >= cxx23); > > if (!ctx->quiet) > > error_at (loc, "%<goto%> is not a constant expression"); > > *non_constant_p = true; > > diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-prvalue5.C > > b/gcc/testsuite/g++.dg/cpp0x/constexpr-prvalue5.C > > new file mode 100644 > > index 00000000000..1f847bbe183 > > --- /dev/null > > +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-prvalue5.C > > @@ -0,0 +1,24 @@ > > +// PR c++/118928 > > +// { dg-do compile { target c++11 } } > > +// { dg-options "-O" } > > + > > +using size_t = decltype(sizeof(0)); > > + > > +namespace std { > > +template <typename T> struct initializer_list { > > + const T *_M_array; > > + size_t _M_len; > > +}; > > +struct S { > > + constexpr S(const char *); // { dg-warning "used but never defined" } > > +}; > > +struct vector { > > + constexpr vector(initializer_list<S>) {} > > +}; > > +} > > +struct Y { > > + std::vector v; > > +}; > > +struct X { > > + Y y{{""}}; > > +} x; > > > > base-commit: a2755339c6c9832467c573d956e91565943ecdc1 > Marek