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

Reply via email to