On 8/5/26 7:11 AM, Jakub Jelinek wrote:
On Tue, Aug 04, 2026 at 09:46:21PM -0400, Jason Merrill wrote:
Nice.
But it seems to me that once we cache the lookups this way, we don't need to
determine the set of designators that belong to the current base; we should
be able to look them all up and let the normal handling work from there.
I felt awkward about continuing to ask you for changes, so I poked at it
some myself. The first patch changes reshape_init_class to avoid changing
d->end, and I think makes sense to combine with your patch.
Thanks. I've looked at your first patch and it looks correct to me and indeed
simplifies stuff.
It would also be good to check -Wmissing-braces in at least one of the new
testcases.
I've added -Wmissing-braces coverage into desig14.C now, see incremental
diff here and attached full patch (my last patch + your simplify patch
+ this incremental).
So far tested with
GXX_TESTSUITE_STDS=98,11,14,17,20,23,26,29 make check-g++
RUNTESTFLAGS="dg.exp='desig* feat-cxx29.C pr43765.C embed-14.C'"
together, ok for trunk if it passes full bootstrap/regtest?
OK, thanks.
The second patch changes _class to go through reshape_init_r for this case
instead of directly recursing into reshape_init_class, which avoids the
duplication of -Wmissing-braces handling. This required more adjustment of
reshape_init_r than I expected, so I'm inclined to make it a followup, but I
think it's a useful clarification.
Not sure if I understood all the details but I haven't tried much yet.
If it can go in separately, doesn't have to be done immediately.
--- gcc/testsuite/g++.dg/cpp29/desig14.C.jj 2026-08-05 12:33:10.574200452
+0200
+++ gcc/testsuite/g++.dg/cpp29/desig14.C 2026-08-05 12:57:26.171939454
+0200
@@ -1,14 +1,23 @@
// C++29 P2287R6 - Designated-initializers for Base Classes
// { dg-do compile { target c++20 } }
-// { dg-options "" }
+// { dg-options "-Wmissing-braces" }
struct A { int a, b; };
struct B { int c, d; };
struct C : A, B { int e, f; };
+struct D : C { int g; };
auto c1 = C { { .a = 1, .b = 2 }, { .c = 3, .d = 4 }, .e = 5, .f = 6 }; // { dg-warning
"either all initializer clauses should be designated or none of them should be"
"" { target c++26_down } }
auto c2 = C { { .a = 1, .b = 2 }, .e = 5, .f = 6 }; // { dg-warning
"either all initializer clauses should be designated or none of them should be"
"" { target c++26_down } }
auto c3 = C { {}, { .c = 3, .d = 4 }, .f = 6 }; // { dg-warning
"either all initializer clauses should be designated or none of them should be"
"" { target c++26_down } }
auto c4 = C { .e = 1, 2 }; // { dg-error "either
all initializer clauses should be designated or none of them should be" "" { target
c++26_down } }
// { dg-error
"designated initializer clause should not be followed by non-designated" "" {
target c++29 } .-1 }
+auto c5 = C { .a = 1, .b = 2, .c = 3, .d = 4, .e = 5, .f = 6 }; // { dg-error
"'C' has no non-static data member named 'a'" "" { target c++26_down } }
+ // { dg-warning
"missing braces around initializer for 'A'" "" { target c++29 } .-1 }
+ // { dg-warning
"missing braces around initializer for 'B'" "" { target c++29 } .-2 }
auto a1 = A { 1, .b = 2 }; // { dg-error
"last non-designated initializer clause does not appertain to a base class
subobject" }
// { dg-warning
"either all initializer clauses should be designated or none of them should be"
"" { target c++26_down } .-1 }
+auto d1 = D { .a = 1, .b = 2, .c = 3, .d = 4, .e = 5, .f = 6, .g = 7 }; // { dg-error
"'D' has no non-static data member named 'a'" "" { target c++26_down } }
+ // { dg-warning
"missing braces around initializer for 'A'" "" { target c++29 } .-1 }
+ // { dg-warning
"missing braces around initializer for 'B'" "" { target c++29 } .-2 }
+ // { dg-warning
"missing braces around initializer for 'C'" "" { target c++29 } .-3 }
+auto d2 = D { { { .a = 1, .b = 2 }, { .c = 3, .d = 4 }, .e = 5, .f = 6 }, .g = 7 }; // {
dg-warning "either all initializer clauses should be designated or none of them should
be" "" { target c++26_down } }
Jakub