On Fri, Jul 24, 2026 at 09:41:34PM +0200, Jakub Jelinek wrote:
> On Fri, Jul 24, 2026 at 03:15:25PM -0400, Jason Merrill wrote:
> > Ah, good point.  It might make sense to do all the lookups in a first pass
> > and change the indices to the FIELD_DECLs (and remove the assert/update the
> > comment that we don't do this)?
> 
> I can try.  That would just save the lookup during recursion, but not e.g. the
> discovery of which base class (if any) it belongs to, that will need to be
> done again and again during recursion.

Actually, I think changing d->cur->index or new_end->index is wrong.
If we have say
struct A { int a, b; };
struct B : A { int c; };
struct C { int a, b, d; };
struct D : C { int e, c; };
void foo (B, A);
void foo (D, C);
void bar () { foo ({ .a = 1, .b = 2, .c = 3 }, { .d = 1 }); }
then it first checks if calling the first foo overload is viable.  Now,
d->cur points to the CONSTRUCTOR_ELTS of the original shared CONSTRUCTOR
with IDENTIFIER_NODE a, b, c.  If reshape_init_class modifies it in place
to avoid the extra lookups (see incremental patch below), it will work
just fine during that call, we later found out the second argument is
not suitable for A, so continue with the next overload, but at this point
we have a CONSTRUCTOR which has been modified, doesn't have IDENTIFIER_NODE
indices but FIELD_DECLs from A.  While the second overload is usable in
this case, we think it is not appropriate.
Will add this to the testsuite.

> > That's what I was thinking, yes.
> 
> Ok.

Done with the changes, now to cover it in the testsuite.

--- gcc/cp/decl.cc.jj   2026-07-25 12:56:25.349098545 +0200
+++ gcc/cp/decl.cc      2026-07-25 12:54:46.527399194 +0200
@@ -7850,16 +7850,9 @@ reshape_init_class (tree type, reshape_i
 
          if (TREE_CODE (d->cur->index) == FIELD_DECL)
            {
-             /* We already reshaped this; we should have returned early from
-                reshape_init.  */
-             gcc_checking_assert (false);
-             if (field != d->cur->index)
-               {
-                 if (tree id = DECL_NAME (d->cur->index))
-                   gcc_checking_assert (d->cur->index
-                                        == get_class_binding (type, id));
-                 field = d->cur->index;
-               }
+             CONSTRUCTOR_IS_DESIGNATED_INIT (new_init) = true;
+             direct_desig = true;
+             field = d->cur->index;
            }
          else if (TREE_CODE (d->cur->index) == IDENTIFIER_NODE)
            {
@@ -7965,6 +7958,7 @@ reshape_init_class (tree type, reshape_i
                          if (!field || TREE_CODE (field) != FIELD_DECL)
                            break;
 
+                         new_end->index = field;
                          tree nictx = DECL_CONTEXT (field);
                          if (same_type_ignoring_top_level_qualifiers_p (nictx,
                                                                         type))


        Jakub

Reply via email to