On Fri, May 15, 2026 at 06:05:29PM -0400, Patrick Palka wrote:
> On Fri, 15 May 2026, Marek Polacek wrote:
> 
> > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/branches?
> > 
> > -- >8 --
> > When looking into 125315 I came up with another test that crashes
> > due to an empty object.  It still crashes even after Jason's patch.
> > 
> > Here we have a subobject nested in an empty object:
> > 
> >   {.w = {.v = TARGET_EXPR <f(s)>}}
> > 
> > w's type is W, an empty union due to [[no_unique_address]], so
> > init_subob_ctx clears the ctor, but then we recurse to
> > 
> >   {.v = TARGET_EXPR <f(s)>}
> > 
> > with a null ctx->ctor so the call to get_or_insert_ctor_field in
> > cxx_eval_bare_aggregate crashes.  This fixes the crash similarly
> > to c++/125315.
> > 
> > no_unique_address18.C worked fine even before this patch because
> > there we don't have an empty object.  But let's test it also.
> > 
> >     PR c++/125336
> > 
> > gcc/cp/ChangeLog:
> > 
> >     * constexpr.cc (cxx_eval_bare_aggregate): Don't call
> >     get_or_insert_ctor_field when there is no CONSTRUCTOR.  Assert
> >     is_empty_class.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> >     * g++.dg/cpp2a/no_unique_address17.C: New test.
> >     * g++.dg/cpp2a/no_unique_address18.C: New test.
> > ---
> >  gcc/cp/constexpr.cc                              |  8 ++++++--
> >  gcc/testsuite/g++.dg/cpp2a/no_unique_address17.C | 12 ++++++++++++
> >  gcc/testsuite/g++.dg/cpp2a/no_unique_address18.C | 12 ++++++++++++
> >  3 files changed, 30 insertions(+), 2 deletions(-)
> >  create mode 100644 gcc/testsuite/g++.dg/cpp2a/no_unique_address17.C
> >  create mode 100644 gcc/testsuite/g++.dg/cpp2a/no_unique_address18.C
> > 
> > diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
> > index 1fc8a56503c..84896170d05 100644
> > --- a/gcc/cp/constexpr.cc
> > +++ b/gcc/cp/constexpr.cc
> > @@ -6841,7 +6841,11 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, 
> > tree t,
> >        /* Like in cxx_eval_store_expression, omit entries for empty fields. 
> >  */
> >        bool no_slot = new_ctx.ctor == NULL_TREE;
> >        int pos_hint = -1;
> > -      if (new_ctx.ctor != ctx->ctor && !no_slot)
> > +      if (!ctx->ctor)
> > +   /* The enclosing object could be an empty subobject so we have no
> > +      CONSTRUCTOR (c++/125336).  */
> > +   gcc_checking_assert (is_empty_class (type));
> > +      else if (new_ctx.ctor != ctx->ctor && !no_slot)
> >     {
> >       /* If we built a new CONSTRUCTOR, attach it now so that other
> >          initializers can refer to it.  */
> > @@ -6892,7 +6896,7 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, 
> > tree t,
> >       gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (index))));
> >       changed = true;
> >     }
> > -      else
> > +      else if (ctx->ctor)
> >     {
> >       if (TREE_CODE (type) == UNION_TYPE
> >           && (*p)->last().index != index)
> > diff --git a/gcc/testsuite/g++.dg/cpp2a/no_unique_address17.C 
> > b/gcc/testsuite/g++.dg/cpp2a/no_unique_address17.C
> > new file mode 100644
> > index 00000000000..11099698a9b
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/cpp2a/no_unique_address17.C
> > @@ -0,0 +1,12 @@
> > +// PR c++/125336
> > +// { dg-do compile { target c++20 } }
> > +// { dg-prune-output "used but never defined" }
> 
> The "used but never defined" warning implies the testcase is UB right?
> Would be nice to have a valid testcase that triggers this bug.

It would be very nice but I don't know how to construct such
a test.  If the class didn't have to be empty, I would know
how.  To exhibit the problem we need to call cxx_eval_bare_aggregate
which is not going to happen when the CONSTRUCTOR is constant.  If
a constexpr function calls a non-constexpr function, we trigger the
bug but it's again invalid code.  This is valid but it doesn't show
the ICE because we don't have a nested { }:

struct A { constexpr A(int) { } };
struct S { [[no_unique_address]] A a; };
constexpr S f(int n) { return S{A{n}}; }
union W {
  [[no_unique_address]] S v;
};
struct R { W w; };
auto x = R{{ f(1) }};

Marek

Reply via email to