https://gcc.gnu.org/g:d609ca7423dc3bae4b971a16303129d95512acac

commit r17-3010-gd609ca7423dc3bae4b971a16303129d95512acac
Author: Jakub Jelinek <[email protected]>
Date:   Thu Aug 6 10:51:44 2026 +0200

    c++: implement C++29 P2287R6 - Designated-initializers for Base Classes 
[PR125989]
    
    The following patch implements the C++29 P2287R6
    Designated-initializers for Base Classes
    paper.
    One change is during parsing, to match the new designated-initializer-list
    grammar, the patch allows non-designated clauses followed by designated
    clauses for C++29 or for C++20 to C++26 as pedwarned extension (but rejects
    designated followed by non-designated and also when using GNU style
    [0] = designators non-designated by designated with that GNU array style,
    while the grammar allows now in theory
    { 1, 2, [3] = 3, [4] = 4 } in theory I think it is undesirable to allow
    that mixing, the designated after non-designated has been added solely
    for base classes and arrays don't have those).
    Another change is in the if (first_desig && cxx_dialect >= cxx20) hunk,
    to reject non-designated clause which doesn't appertain to base class
    followed by designated clause.
    Yet another change is the lookup_member as fallback to get_class_binding,
    but according to the paper it shouldn't replace it, even if there is
    ambiguity, if the designator names a NSDM of current class, that should
    be what is used, only if it is an ambiguity inside of base classes there
    should be an error.
    And finally, if field for C++29 is from some base class, find out the
    corresponding base FIELD_DECL and find out how many consecutive designators
    belong to the same FIELD_DECL and recurse using reshape_init_r.
    
    2026-08-06  Jakub Jelinek  <[email protected]>
                Jason Merrill  <[email protected]>
    
            PR c++/125989
    gcc/c-family/
            * c-cppbuiltin.cc (c_cpp_builtins): Predefine
            __cpp_designated_initializers to 202606 instead of 201707 for
            C++29.
    gcc/cp/
            * parser.cc: Implement C++29 P2287R6 - Designated-initializers for
            Base Classes.
            (cp_parser_initializer_list): For C++29, allow non-designated 
clauses
            followed by designated ones, provided designators are identifiers.
            For C++20-26, allow that as a pedwarned about extension but use the
            C++20 wording in that case.
            * decl.cc (reshape_init_class): Diagnose non-designated clause not
            appertaining to base class followed by designated clause for C++ >= 
20.
            For C++29, if get_class_binding for designator is unsuccessful, use
            lookup_member afterwards and handle the case where the lookup 
succeeds
            for some member of a base class through recursive 
reshape_init_class.
    gcc/testsuite/
            * g++.dg/cpp/embed-14.C: Expect different diagnostics for C++29 and
            sometimes for C++20-C++26 too.
            * g++.dg/cpp2a/desig2.C: Likewise.
            * g++.dg/cpp2a/desig13.C: Likewise.
            * g++.dg/cpp2a/desig20.C: Likewise.
            * g++.dg/ext/desig4.C: Likewise.
            * g++.dg/parse/pr43765.C: Likewise.
            * g++.dg/cpp29/feat-cxx29.C: Expect different value of
            __cpp_designated_initializers for C++29.
            * g++.dg/cpp29/desig1.C: New test.
            * g++.dg/cpp29/desig2.C: New test.
            * g++.dg/cpp29/desig3.C: New test.
            * g++.dg/cpp29/desig4.C: New test.
            * g++.dg/cpp29/desig5.C: New test.
            * g++.dg/cpp29/desig6.C: New test.
            * g++.dg/cpp29/desig7.C: New test.
            * g++.dg/cpp29/desig8.C: New test.
            * g++.dg/cpp29/desig9.C: New test.
            * g++.dg/cpp29/desig10.C: New test.
            * g++.dg/cpp29/desig11.C: New test.
            * g++.dg/cpp29/desig12.C: New test.
            * g++.dg/cpp29/desig13.C: New test.
            * g++.dg/cpp29/desig14.C: New test.
            * g++.dg/cpp29/desig15.C: New test.
            * g++.dg/cpp29/desig16.C: New test.
    
    Reviewed-by: Jason Merrill <[email protected]>

Diff:
---
 gcc/c-family/c-cppbuiltin.cc            |   4 +-
 gcc/cp/decl.cc                          | 122 +++++++++++++++++++++++++++++---
 gcc/cp/parser.cc                        |  32 +++++++--
 gcc/testsuite/g++.dg/cpp/embed-14.C     |   4 +-
 gcc/testsuite/g++.dg/cpp29/desig1.C     |  12 ++++
 gcc/testsuite/g++.dg/cpp29/desig10.C    |  43 +++++++++++
 gcc/testsuite/g++.dg/cpp29/desig11.C    |  21 ++++++
 gcc/testsuite/g++.dg/cpp29/desig12.C    |  13 ++++
 gcc/testsuite/g++.dg/cpp29/desig13.C    |  14 ++++
 gcc/testsuite/g++.dg/cpp29/desig14.C    |  23 ++++++
 gcc/testsuite/g++.dg/cpp29/desig15.C    |  15 ++++
 gcc/testsuite/g++.dg/cpp29/desig16.C    |  13 ++++
 gcc/testsuite/g++.dg/cpp29/desig2.C     |   9 +++
 gcc/testsuite/g++.dg/cpp29/desig3.C     |  41 +++++++++++
 gcc/testsuite/g++.dg/cpp29/desig4.C     |  13 ++++
 gcc/testsuite/g++.dg/cpp29/desig5.C     |  25 +++++++
 gcc/testsuite/g++.dg/cpp29/desig6.C     |  16 +++++
 gcc/testsuite/g++.dg/cpp29/desig7.C     |  10 +++
 gcc/testsuite/g++.dg/cpp29/desig8.C     |  19 +++++
 gcc/testsuite/g++.dg/cpp29/desig9.C     |  12 ++++
 gcc/testsuite/g++.dg/cpp29/feat-cxx29.C |   4 +-
 gcc/testsuite/g++.dg/cpp2a/desig13.C    |   3 +-
 gcc/testsuite/g++.dg/cpp2a/desig2.C     |   6 +-
 gcc/testsuite/g++.dg/cpp2a/desig20.C    |   2 +-
 gcc/testsuite/g++.dg/ext/desig4.C       |   9 +--
 gcc/testsuite/g++.dg/parse/pr43765.C    |   5 +-
 26 files changed, 460 insertions(+), 30 deletions(-)

diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc
index a9cbd6b6f244..2399b24a0484 100644
--- a/gcc/c-family/c-cppbuiltin.cc
+++ b/gcc/c-family/c-cppbuiltin.cc
@@ -1072,7 +1072,8 @@ c_cpp_builtins (cpp_reader *pfile)
          /* Set feature test macros for C++20.  */
          cpp_define (pfile, "__cpp_init_captures=201803L");
          cpp_define (pfile, "__cpp_generic_lambdas=201707L");
-         cpp_define (pfile, "__cpp_designated_initializers=201707L");
+         if (cxx_dialect <= cxx26)
+           cpp_define (pfile, "__cpp_designated_initializers=201707L");
          if (cxx_dialect <= cxx20)
            cpp_define (pfile, "__cpp_constexpr=202002L");
          cpp_define (pfile, "__cpp_constexpr_in_decltype=201711L");
@@ -1129,6 +1130,7 @@ c_cpp_builtins (cpp_reader *pfile)
        {
          /* Set feature test macros for C++29.  */
          cpp_define (pfile, "__cpp_pp_embed=202606L");
+         cpp_define (pfile, "__cpp_designated_initializers=202606L");
        }
       if (flag_concepts && cxx_dialect > cxx14)
        cpp_define (pfile, "__cpp_concepts=202002L");
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 41aae747c955..b5d9ed058748 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -7829,8 +7829,25 @@ reshape_init_class (tree type, reshape_iter *d, bool 
first_initializer_p,
       return new_init;
     }
 
+  /* For C++29 designated initializers we do modify d->cur->index in place
+     to cache name lookup results.  Make sure to undo it before returning.  */
+  struct designator_undo {
+    constructor_elt *start, *end;
+    void undo ()
+    {
+      while (start != end)
+       {
+         start->index = DECL_NAME (start->index);
+         ++start;
+       }
+      start = end = nullptr;
+    }
+    ~designator_undo () { undo (); }
+  } desig_undo = { nullptr, nullptr };
+
   /* For C++20 CTAD, handle pack expansions in the base list.  */
   tree last_was_pack_expansion = NULL_TREE;
+  bool first_desig = true;
 
   /* Loop through the initializable fields, gathering initializers.  */
   while (d->cur != d->end)
@@ -7839,6 +7856,7 @@ reshape_init_class (tree type, reshape_iter *d, bool 
first_initializer_p,
       constructor_elt *old_cur = d->cur;
       unsigned old_raw_idx = d->raw_idx;
       bool direct_desig = false;
+      bool subclass = false;
 
       /* Handle C++20 designated initializers.  */
       if (d->cur->index)
@@ -7848,22 +7866,37 @@ reshape_init_class (tree type, reshape_iter *d, bool 
first_initializer_p,
 
          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)
            {
+             if (first_desig && cxx_dialect >= cxx20)
+               {
+                 if (CONSTRUCTOR_NELTS (new_init))
+                   {
+                     constructor_elt *last
+                       = &CONSTRUCTOR_ELTS (new_init)->last ();
+                     if (last->index == NULL_TREE
+                         || TREE_CODE (last->index) != FIELD_DECL
+                         || !DECL_FIELD_IS_BASE (last->index))
+                       {
+                         if (complain & tf_error)
+                           error ("last non-designated initializer clause "
+                                  "does not appertain to a base class "
+                                  "subobject");
+                         return error_mark_node;
+                       }
+                   }
+                 first_desig = false;
+               }
              CONSTRUCTOR_IS_DESIGNATED_INIT (new_init) = true;
              field = get_class_binding (type, d->cur->index);
              direct_desig = true;
+             if (!field && cxx_dialect >= cxx29)
+               field = lookup_member (type, d->cur->index, /*protect=*/2,
+                                      /*want_type=*/false, complain);
            }
          else
            {
@@ -7913,6 +7946,62 @@ reshape_init_class (tree type, reshape_iter *d, bool 
first_initializer_p,
                  ictx = cctx;
                }
 
+             /* In C++29 a designator can name a member of a base; in that
+                case, go through the designators and replace ids with _DECLs
+                to record the lookup for the most-derived class.  */
+             if (cxx_dialect >= cxx29)
+               {
+                 tree ibinfo = lookup_base (type, ictx, ba_unique, NULL,
+                                            complain);
+                 if (!ibinfo)
+                   /* The designator names a field outside this base class,
+                      so we're done.  */
+                   break;
+                 else if (ibinfo != error_mark_node)
+                   {
+                     while (BINFO_INHERITANCE_CHAIN (ibinfo) != binfo)
+                       ibinfo = BINFO_INHERITANCE_CHAIN (ibinfo);
+                     ictx = TREE_TYPE (ibinfo);
+
+                     desig_undo.undo ();
+
+                     if (d->cur->index != field)
+                       {
+                         d->cur->index = field;
+                         desig_undo.start = d->cur;
+                       }
+                     constructor_elt *e = d->cur + 1;
+                     for (; e != d->end; ++e)
+                       {
+                         if (e->index == NULL_TREE
+                             || e->index == error_mark_node)
+                           break;
+                         if (desig_undo.start)
+                           {
+                             gcc_assert (TREE_CODE (e->index)
+                                         == IDENTIFIER_NODE);
+                             field = lookup_member (type, e->index,
+                                                    /*protect=*/2,
+                                                    /*want_type=*/false,
+                                                    tf_none);
+                             if (!field || TREE_CODE (field) != FIELD_DECL)
+                               break;
+                           }
+                         else
+                           {
+                             gcc_assert (TREE_CODE (e->index) == FIELD_DECL);
+                             field = e->index;
+                           }
+
+                         if (desig_undo.start)
+                           e->index = field;
+                       }
+                     if (desig_undo.start)
+                       desig_undo.end = e;
+                     goto found;
+                   }
+               }
+
              /* Not found, e.g. FIELD is a member of a base class.  */
              if (complain & tf_error)
                error ("%qD is not a direct member of %qT", field, type);
@@ -7927,6 +8016,7 @@ reshape_init_class (tree type, reshape_iter *d, bool 
first_initializer_p,
              gcc_assert (aafield);
              field = aafield;
              direct_desig = false;
+             subclass = true;
            }
        }
 
@@ -7958,6 +8048,18 @@ reshape_init_class (tree type, reshape_iter *d, bool 
first_initializer_p,
                                            d->cur->value, complain);
          d->cur++;
        }
+      else if (subclass)
+       {
+         if (complain & tf_warning)
+           warning (OPT_Wmissing_braces,
+                    "missing braces around initializer for %qT",
+                    TREE_TYPE (field));
+         field_init = reshape_init_class (TREE_TYPE (field), d,
+                                          /*first_initializer_p=*/NULL_TREE,
+                                          complain);
+         if (TREE_CODE (field_init) == CONSTRUCTOR)
+           CONSTRUCTOR_BRACES_ELIDED_P (field_init) = true;
+       }
       else
        field_init = reshape_init_r (TREE_TYPE (field), d,
                                     /*first_initializer_p=*/NULL_TREE,
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index b1a1157afda4..3b4de7c7d3a3 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -29462,13 +29462,35 @@ cp_parser_initializer_list (cp_parser* parser, bool* 
non_constant_p,
        }
       else if (cxx_dialect >= cxx20
               && first_designator != error_mark_node
-              && (!first_designator != !designator))
+              && (!first_designator != !designator)
+              && (cxx_dialect < cxx29
+                  || first_designator
+                  || TREE_CODE (designator) != IDENTIFIER_NODE))
        {
-         error_at (loc, "either all initializer clauses should be designated "
-                        "or none of them should be");
-         first_designator = error_mark_node;
+         if (cxx_dialect < cxx29
+             && !first_designator
+             && TREE_CODE (designator) == IDENTIFIER_NODE)
+           {
+             pedwarn (loc, OPT_Wc__29_extensions,
+                      "either all initializer clauses should be "
+                      "designated or none of them should be");
+             first_designator = designator;
+           }
+         else
+           {
+             if (cxx_dialect < cxx29
+                 || TREE_CODE (first_designator
+                               ? first_designator
+                               : designator) != IDENTIFIER_NODE)
+               error_at (loc, "either all initializer clauses should be "
+                              "designated or none of them should be");
+             else
+               error_at (loc, "designated initializer clause should not "
+                              "be followed by non-designated");
+             first_designator = error_mark_node;
+           }
        }
-      else if (cxx_dialect < cxx20 && !first_designator)
+      else if (!first_designator)
        first_designator = designator;
 
       /* Parse the initializer.  */
diff --git a/gcc/testsuite/g++.dg/cpp/embed-14.C 
b/gcc/testsuite/g++.dg/cpp/embed-14.C
index 9f4be10409ed..b080728c2f88 100644
--- a/gcc/testsuite/g++.dg/cpp/embed-14.C
+++ b/gcc/testsuite/g++.dg/cpp/embed-14.C
@@ -3,8 +3,8 @@
 
 struct S { int a; long b; unsigned char c[63]; int d; };
 S s = {
-#embed __FILE__ limit (64) prefix (.a = 1, .b = ) suffix (, .d = 2)    // { 
dg-error "either all initializer clauses should be designated or none of them 
should be" "" { target c++20 } }
-};
+#embed __FILE__ limit (64) prefix (.a = 1, .b = ) suffix (, .d = 2)    // { 
dg-error "either all initializer clauses should be designated or none of them 
should be" "" { target { c++20 && c++26_down } } }
+};                                                                     // { 
dg-error "designated initializer clause should not be followed by 
non-designated" "" { target c++29 } .-1 }
 const unsigned char t[66] = {
 #embed __FILE__ limit (64) prefix ([0] = 1, [1] =) suffix (, [65] = 2) // { 
dg-error "either all initializer clauses should be designated or none of them 
should be" "" { target c++20 } }
 };
diff --git a/gcc/testsuite/g++.dg/cpp29/desig1.C 
b/gcc/testsuite/g++.dg/cpp29/desig1.C
new file mode 100644
index 000000000000..824ba9851779
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp29/desig1.C
@@ -0,0 +1,12 @@
+// C++29 P2287R6 - Designated-initializers for Base Classes
+// { dg-do compile { target c++20 } }
+
+struct A { int a; };
+struct B : A { int b; };
+auto b1 = B { { 1 }, 2 };
+auto b2 = B { 1, 2 };
+auto b3 = B { .a = 1, .b = 2 };                // { dg-error "'B' has no 
non-static data member named 'a'" "" { target c++26_down } }
+auto b4 = B { { .a = 1 }, .b = 2 };    // { dg-error "either all initializer 
clauses should be designated or none of them should be" "" { target c++26_down 
} }
+auto b5 = B { .a { 1 }, .b { 2 } };    // { dg-error "'B' has no non-static 
data member named 'a'" "" { target c++26_down } }
+auto b6 = B { .b = 2, .a = 1 };                // { dg-error "designator order 
for field 'B::A' does not match declaration order in 'B'" "" { target c++29 } }
+                                       // { dg-error "'B' has no non-static 
data member named 'a'" "" { target c++26_down } .-1 }
diff --git a/gcc/testsuite/g++.dg/cpp29/desig10.C 
b/gcc/testsuite/g++.dg/cpp29/desig10.C
new file mode 100644
index 000000000000..0baee1ce9367
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp29/desig10.C
@@ -0,0 +1,43 @@
+// C++29 P2287R6 - Designated-initializers for Base Classes
+// { dg-do compile { target c++29 } }
+
+struct A { int a, b, c; };
+struct B { int d, e; };
+struct C : A { int f, g; };
+struct D : B { int h, i; };
+struct E : C, D { int j; };
+constexpr auto e1 = E { .a = 1, .c = 2, .f = 3, .d = 4, .i = 5, .j = 6 };
+static_assert (e1.a == 1 && e1.b == 0 && e1.c == 2 && e1.f == 3 && e1.g == 0
+              && e1.d == 4 && e1.e == 0 && e1.h == 0 && e1.i == 5 && e1.j == 
6);
+auto e2 = E { 1, 2, 3, 4, 5, .j = 6 }; // { dg-error "last non-designated 
initializer clause does not appertain to a base class subobject" }
+constexpr auto e3 = E { { .a = 1, .b = 2 }, .j = 3 };
+static_assert (e3.a == 1 && e3.b == 2 && e3.c == 0 && e3.f == 0 && e3.g == 0
+              && e3.d == 0 && e3.e == 0 && e3.h == 0 && e3.i == 0 && e3.j == 
3);
+constexpr auto e4 = E { {}, { { .e = 1 }, .i = 2 }, .j = 3 };
+static_assert (e4.a == 0 && e4.b == 0 && e4.c == 0 && e4.f == 0 && e4.g == 0
+              && e4.d == 0 && e4.e == 1 && e4.h == 0 && e4.i == 2 && e4.j == 
3);
+constexpr auto e5 = E { { { .b = 1 }, .f = 2 }, { { .d = 3 }, .h = 4 }, .j = 5 
};
+static_assert (e5.a == 0 && e5.b == 1 && e5.c == 0 && e5.f == 2 && e5.g == 0
+              && e5.d == 3 && e5.e == 0 && e5.h == 4 && e5.i == 0 && e5.j == 
5);
+constexpr auto e6 = E { .a = 1, .b = 2, .c = 3, .f = 4, .g = 5, .d = 6,
+                       .e = 7, .h = 8, .i = 9, .j = 10 };
+static_assert (e6.a == 1 && e6.b == 2 && e6.c == 3 && e6.f == 4 && e6.g == 5
+              && e6.d == 6 && e6.e == 7 && e6.h == 8 && e6.i == 9 && e6.j == 
10);
+auto e7 = E { .a = 1, .b = 2, .c = 3, .d = 4, .e = 5, .f = 6, .g = 7,
+             .h = 8, .i = 9, .j = 10 };// { dg-error "designator order for 
field 'E::C' does not match declaration order in 'E'" }
+auto e8 = E { {}, {}, .a = 1, .j = 2 };        // { dg-error "designator order 
for field 'E::C' does not match declaration order in 'E'" }
+auto e9 = E { {}, .f = 1 };            // { dg-error "designator order for 
field 'E::C' does not match declaration order in 'E'" }
+auto e10 = E { {}, {}, .e = 1 };       // { dg-error "designator order for 
field 'E::D' does not match declaration order in 'E'" }
+auto e11 = E { {}, {}, .h = 1 };       // { dg-error "designator order for 
field 'E::D' does not match declaration order in 'E'" }
+auto e12 = E { .a = 0, .b = 0, .c = 0, .d = 0, .e = 0, .f = 0, .g = 0, .h = 0, 
.i = 0, .j = 0,
+              .a = 0, .b = 0, .c = 0, .d = 0, .e = 0, .f = 0, .g = 0, .h = 0, 
.i = 0, .j = 0 };
+// { dg-error "'.a' designator used multiple times in the same initializer 
list" "" { target *-*-* } .-1 }
+// { dg-error "'.b' designator used multiple times in the same initializer 
list" "" { target *-*-* } .-2 }
+// { dg-error "'.c' designator used multiple times in the same initializer 
list" "" { target *-*-* } .-3 }
+// { dg-error "'.d' designator used multiple times in the same initializer 
list" "" { target *-*-* } .-4 }
+// { dg-error "'.e' designator used multiple times in the same initializer 
list" "" { target *-*-* } .-5 }
+// { dg-error "'.f' designator used multiple times in the same initializer 
list" "" { target *-*-* } .-6 }
+// { dg-error "'.g' designator used multiple times in the same initializer 
list" "" { target *-*-* } .-7 }
+// { dg-error "'.h' designator used multiple times in the same initializer 
list" "" { target *-*-* } .-8 }
+// { dg-error "'.i' designator used multiple times in the same initializer 
list" "" { target *-*-* } .-9 }
+// { dg-error "'.j' designator used multiple times in the same initializer 
list" "" { target *-*-* } .-10 }
diff --git a/gcc/testsuite/g++.dg/cpp29/desig11.C 
b/gcc/testsuite/g++.dg/cpp29/desig11.C
new file mode 100644
index 000000000000..fa126c7cdfad
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp29/desig11.C
@@ -0,0 +1,21 @@
+// C++29 P2287R6 - Designated-initializers for Base Classes
+// { dg-do compile { target c++29 } }
+
+struct A { int a, x; };
+struct B { int b, x; };
+struct C : A, B { int c; };
+struct D : C { int x; };
+constexpr auto d = D { .c = 1, .x = 2 };
+static_assert (d.a == 0 && d.A::x == 0 && d.b == 0 && d.B::x == 0
+              && d.c == 1 && d.D::x == 2);
+struct E { int a, x; };
+struct F : E { int x; };
+constexpr auto f = F { .a = 1, .x = 2 };
+static_assert (f.a == 1 && f.E::x == 0 && f.F::x == 2);
+struct G { int a, b; };
+struct H : G { int c; };
+struct I { int a, b, d; };
+struct J : I { int e, c; };
+constexpr int foo (H, G) { return 1; }
+constexpr int foo (J, I) { return 42; }
+static_assert (foo ({ .a = 1, .b = 2, .c = 3 }, { .d = 1 }) == 42);
diff --git a/gcc/testsuite/g++.dg/cpp29/desig12.C 
b/gcc/testsuite/g++.dg/cpp29/desig12.C
new file mode 100644
index 000000000000..5059487fd6ba
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp29/desig12.C
@@ -0,0 +1,13 @@
+// C++29 P2287R6 - Designated-initializers for Base Classes
+// { dg-do compile { target c++20 } }
+// { dg-options "-Wno-c++29-extensions" }
+
+struct A { int a, b; };
+struct B { int c, d; };
+struct C : A, B { int e, f; };
+auto c1 = C { { .a = 1, .b = 2 }, { .c = 3, .d = 4 }, .e = 5, .f = 6 };
+auto c2 = C { { .a = 1, .b = 2 }, .e = 5, .f = 6 };
+auto c3 = C { {}, { .c = 3, .d = 4 }, .f = 6 };
+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 a1 = A { 1, .b = 2 };     // { dg-error "last non-designated initializer 
clause does not appertain to a base class subobject" }
diff --git a/gcc/testsuite/g++.dg/cpp29/desig13.C 
b/gcc/testsuite/g++.dg/cpp29/desig13.C
new file mode 100644
index 000000000000..6ff50b3160be
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp29/desig13.C
@@ -0,0 +1,14 @@
+// C++29 P2287R6 - Designated-initializers for Base Classes
+// { dg-do compile { target c++20 } }
+// { dg-options "-Wc++29-extensions" }
+
+struct A { int a, b; };
+struct B { int c, d; };
+struct C : A, B { int e, f; };
+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 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 }
diff --git a/gcc/testsuite/g++.dg/cpp29/desig14.C 
b/gcc/testsuite/g++.dg/cpp29/desig14.C
new file mode 100644
index 000000000000..9c9983b93a45
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp29/desig14.C
@@ -0,0 +1,23 @@
+// C++29 P2287R6 - Designated-initializers for Base Classes
+// { dg-do compile { target c++20 } }
+// { 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 } }
diff --git a/gcc/testsuite/g++.dg/cpp29/desig15.C 
b/gcc/testsuite/g++.dg/cpp29/desig15.C
new file mode 100644
index 000000000000..692cec8e2653
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp29/desig15.C
@@ -0,0 +1,15 @@
+// C++29 P2287R6 - Designated-initializers for Base Classes
+// { dg-do compile { target c++20 } }
+// { dg-options "-Werror=c++29-extensions" }
+
+struct A { int a, b; };
+struct B { int c, d; };
+struct C : A, B { int e, f; };
+auto c1 = C { { .a = 1, .b = 2 }, { .c = 3, .d = 4 }, .e = 5, .f = 6 };        
// { dg-error "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-error "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-error "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 a1 = A { 1, .b = 2 };                                             // { 
dg-error "last non-designated initializer clause does not appertain to a base 
class subobject" }
+                                                                       // { 
dg-error "either all initializer clauses should be designated or none of them 
should be" "" { target c++26_down } .-1 }
+                                                                       // { 
dg-message "some warnings being treated as errors" "" { target c++26_down } 0 }
diff --git a/gcc/testsuite/g++.dg/cpp29/desig16.C 
b/gcc/testsuite/g++.dg/cpp29/desig16.C
new file mode 100644
index 000000000000..93568a3bb0bf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp29/desig16.C
@@ -0,0 +1,13 @@
+// C++29 P2287R6 - Designated-initializers for Base Classes
+// { dg-do compile { target c++20 } }
+
+struct A { int a, b; };
+struct B { int c, d; };
+struct C : A, B { int e, f; };
+auto c1 = C { { .a = 1, .b = 2 }, { .c = 3, .d = 4 }, .e = 5, .f = 6 };        
// { dg-error "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-error "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-error "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 a1 = A { 1, .b = 2 };                                             // { 
dg-error "last non-designated initializer clause does not appertain to a base 
class subobject" }
+                                                                       // { 
dg-error "either all initializer clauses should be designated or none of them 
should be" "" { target c++26_down } .-1 }
diff --git a/gcc/testsuite/g++.dg/cpp29/desig2.C 
b/gcc/testsuite/g++.dg/cpp29/desig2.C
new file mode 100644
index 000000000000..b21028f95f96
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp29/desig2.C
@@ -0,0 +1,9 @@
+// C++29 P2287R6 - Designated-initializers for Base Classes
+// { dg-do compile { target c++20 } }
+
+struct A { A (const char *); int a; };
+struct B : A { int b, c; };
+auto b1 = B { "hello", .b = 3, .c = 4 };       // { dg-error "either all 
initializer clauses should be designated or none of them should be" "" { target 
c++26_down } }
+auto b2 = B { { "hello" }, .b = 3, .c = 4 };   // { dg-error "either all 
initializer clauses should be designated or none of them should be" "" { target 
c++26_down } }
+auto b3 = B { "nope", 3, .c = 4 };             // { dg-error "last 
non-designated initializer clause does not appertain to a base class subobject" 
}
+                                               // { dg-error "either all 
initializer clauses should be designated or none of them should be" "" { target 
c++26_down } .-1 }
diff --git a/gcc/testsuite/g++.dg/cpp29/desig3.C 
b/gcc/testsuite/g++.dg/cpp29/desig3.C
new file mode 100644
index 000000000000..659a9e2e83eb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp29/desig3.C
@@ -0,0 +1,41 @@
+// C++29 P2287R6 - Designated-initializers for Base Classes
+// { dg-do compile { target c++29 } }
+
+struct A { int a; };
+struct B : A { int b; };
+constexpr auto b1 = B { { 1 }, 2 };
+constexpr auto b2 = B { 3, 4 };
+constexpr auto b3 = B { .a = 5, .b = 6 };
+constexpr auto b4 = B { { .a = 7 }, .b = 8 };
+constexpr auto b5 = B { .a { 9 }, .b { 10 } };
+static_assert (b1.a == 1 && b1.b == 2);
+static_assert (b2.a == 3 && b2.b == 4);
+static_assert (b3.a == 5 && b3.b == 6);
+static_assert (b4.a == 7 && b4.b == 8);
+static_assert (b5.a == 9 && b5.b == 10);
+
+struct C { constexpr C (const char *x) : a (0) { while (*x) a += *x++; } int 
a; };
+struct D : C { int b, c; };
+constexpr auto d1 = D { "abc", .b = 3, .c = 4 };
+constexpr auto d2 = D { { "de" }, .b = 5, .c = 6 };
+static_assert (d1.a == 'a' + 'b' + 'c' && d1.b == 3 && d1.c == 4);
+static_assert (d2.a == 'd' + 'e' && d2.b == 5 && d2.c == 6);
+
+struct E { int x; };
+struct F : E { int x; };
+constexpr auto f1 = F { .x = 1 };
+constexpr auto f2 = F { { .x = 2 }, .x = 3 };
+constexpr auto f3 = F { E { 4 }, .x = 5 };
+static_assert (f1.E::x == 0 && f1.F::x == 1);
+static_assert (f2.E::x == 2 && f2.F::x == 3);
+static_assert (f3.E::x == 4 && f3.F::x == 5);
+
+struct G { int g; };
+struct H { int h; };
+struct I : G, H { int i; };
+constexpr auto i1 = I { { .g = 1 }, { .h = 2 }, .i = 3 };
+constexpr auto i2 = I { { .g = 4 }, .h = 5, .i = 6 };
+constexpr auto i3 = I { { .g = 7 }, H { 8 }, .i = 9 };
+static_assert (i1.g == 1 && i1.h == 2 && i1.i == 3);
+static_assert (i2.g == 4 && i2.h == 5 && i2.i == 6);
+static_assert (i3.g == 7 && i3.h == 8 && i3.i == 9);
diff --git a/gcc/testsuite/g++.dg/cpp29/desig4.C 
b/gcc/testsuite/g++.dg/cpp29/desig4.C
new file mode 100644
index 000000000000..332f2c99266a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp29/desig4.C
@@ -0,0 +1,13 @@
+// C++29 P2287R6 - Designated-initializers for Base Classes
+// { dg-do compile { target c++20 } }
+
+struct F { int f; };
+struct G { int g; };
+struct H : F, G { int h; };
+auto h1 = H { { .f = 1 }, { .g = 2 }, .h = 3 };                // { dg-error 
"either all initializer clauses should be designated or none of them should be" 
"" { target c++26_down } }
+auto h2 = H { { .f = 1 }, .g = 2, .h = 3 };            // { dg-error "either 
all initializer clauses should be designated or none of them should be" "" { 
target c++26_down } }
+                                                       // { dg-error "'H' has 
no non-static data member named 'g'" "" { target c++26_down } .-1 }
+auto h3 = H { { .f = 1 }, G { 2 }, .h = 3 };           // { dg-error "either 
all initializer clauses should be designated or none of them should be" "" { 
target c++26_down } }
+auto h4 = H { { .f = 1 }, { .g = 2 }, .g = 3, .h = 4 };        // { dg-error 
"designator order for field 'H::G' does not match declaration order in 'H'" "" 
{ target c++29 } }
+                                                       // { dg-error "either 
all initializer clauses should be designated or none of them should be" "" { 
target c++26_down } .-1 }
+                                                       // { dg-error "'H' has 
no non-static data member named 'g'" "" { target c++26_down } .-2 }
diff --git a/gcc/testsuite/g++.dg/cpp29/desig5.C 
b/gcc/testsuite/g++.dg/cpp29/desig5.C
new file mode 100644
index 000000000000..89fb6afa0686
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp29/desig5.C
@@ -0,0 +1,25 @@
+// C++29 P2287R6 - Designated-initializers for Base Classes
+// { dg-do compile { target c++20 } }
+
+struct A { int a; };
+struct B : A { int b; };
+struct C : A { C (); int c; };
+struct D : C { int d; };
+
+auto a = A { .a = 1 };
+auto b = B { .a = 1, .b = 2 }; // { dg-error "'B' has no non-static data 
member named 'a'" "" { target c++26_down } }
+auto c = C { .c = 1 };         // { dg-error "designated initializers cannot 
be used with a non-aggregate type 'C'" }
+                               // { dg-error "no matching function for call 
to" "" { target *-*-* } .-1 }
+auto d = D { .a = 1 };         // { dg-error "designated initializers cannot 
be used with a non-aggregate type 'C'" "" { target c++29 } }
+                               // { dg-error "'D' has no non-static data 
member named 'a'" "" { target c++26_down } .-1 }
+
+struct E { int x; };
+struct F : E { int x; };
+constexpr auto f = F { .x = 1 };
+static_assert (f.E::x == 0 && f.F::x == 1);
+
+struct G { int x; };
+struct H { int x; };
+struct I : G, H { };
+auto i = I { .x = 1 };         // { dg-error "request for member 'x' is 
ambiguous" "" { target c++29 } }
+                               // { dg-error "'I' has no non-static data 
member named 'x'" "" { target c++26_down } .-1 }
diff --git a/gcc/testsuite/g++.dg/cpp29/desig6.C 
b/gcc/testsuite/g++.dg/cpp29/desig6.C
new file mode 100644
index 000000000000..78cb09e7a83f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp29/desig6.C
@@ -0,0 +1,16 @@
+// C++29 P2287R6 - Designated-initializers for Base Classes
+// { dg-do compile { target c++29 } }
+
+struct A { int a1, a2; };
+struct B : A { int b; };
+struct C : A { int a1; };
+A v0 = A { 1, .a2 = 2 };                       // { dg-error "last 
non-designated initializer clause does not appertain to a base class subobject" 
}
+constexpr B v1 = B { .a1 = 1, .b = 2 };                // the explicitly 
initialized elements are [A, B::b]
+static_assert (v1.a1 == 1 && v1.a2 == 0 && v1.b == 2);
+constexpr B v2 = B { .a1 = 1, .a2 = 2, .b = 3 };// the explicitly initialized 
elements are [A, B::b]
+static_assert (v2.a1 == 1 && v2.a2 == 2 && v2.b == 3);
+constexpr B v3 = B { A { 1, 2 }, .b = 3 };     // the explicitly initialized 
elements are [A, B::b]
+static_assert (v3.a1 == 1 && v3.a2 == 2 && v3.b == 3);
+B v4 = B { A { }, .a2 = 1, .b = 3 };           // { dg-error "designator order 
for field 'B::A' does not match declaration order in 'B'" }
+constexpr C v5 = C { .a1 = 4 };                        // the explicitly 
initialized elements are [C::a1]
+static_assert (v5.A::a1 == 0 && v5.a2 == 0 && v5.C::a1 == 4);
diff --git a/gcc/testsuite/g++.dg/cpp29/desig7.C 
b/gcc/testsuite/g++.dg/cpp29/desig7.C
new file mode 100644
index 000000000000..6e054cdbb445
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp29/desig7.C
@@ -0,0 +1,10 @@
+// C++29 P2287R6 - Designated-initializers for Base Classes
+// { dg-do compile { target c++29 } }
+
+struct A { int a; };
+struct B : A { int b; };
+struct C : B { int c; };
+constexpr B x = B { .a = 1 };
+static_assert (x.a == 1 && x.b == 0);
+constexpr C y = C { .a = 2, .b = 3, .c = 4 };
+static_assert (y.a == 2 && y.b == 3 && y.c == 4);
diff --git a/gcc/testsuite/g++.dg/cpp29/desig8.C 
b/gcc/testsuite/g++.dg/cpp29/desig8.C
new file mode 100644
index 000000000000..5202bc370ca0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp29/desig8.C
@@ -0,0 +1,19 @@
+// C++29 P2287R6 - Designated-initializers for Base Classes
+// { dg-do compile { target c++29 } }
+
+struct A { int x; int y; int z; };
+A a { .y = 2, .x = 1 };                        // { dg-error "designator order 
for field 'A::x' does not match declaration order in 'A'" }
+constexpr A b { .x = 1, .z = 2 };
+static_assert (b.x == 1 && b.y == 0 && b.z == 2);
+struct B : A { int q; };
+constexpr B e { .x = 1, .q = 3 };
+static_assert (e.x == 1 && e.y == 0 && e.z == 0 && e.q == 3);
+B f { .q = 3, .x = 1 };                        // { dg-error "designator order 
for field 'B::A' does not match declaration order in 'B'" }
+struct C { int p; int x; };
+struct D : A, C { };
+constexpr D g { .y = 1, .p = 2 };
+static_assert (g.A::x == 0 && g.y == 1 && g.z == 0 && g.p == 2 && g.C::x == 0);
+D h { .x = 2 };                                // { dg-error "request for 
member 'x' is ambiguous" }
+struct NonAggr { int na; NonAggr (int); };
+struct E : NonAggr { int e; };
+E i { .na = 1, .e = 2 };               // { dg-error "designated initializers 
cannot be used with a non-aggregate type 'NonAggr'" }
diff --git a/gcc/testsuite/g++.dg/cpp29/desig9.C 
b/gcc/testsuite/g++.dg/cpp29/desig9.C
new file mode 100644
index 000000000000..5cf68984f443
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp29/desig9.C
@@ -0,0 +1,12 @@
+// C++29 P2287R6 - Designated-initializers for Base Classes
+// { dg-do compile { target c++20 } }
+
+struct A { int a; };
+struct B : A { int b; };
+void foo (A);                  // { dg-message "candidate 1: 'void 
foo\\\(A\\\)'" "" { target c++29 } }
+void foo (B);                  // { dg-message "candidate 2: 'void 
foo\\\(B\\\)'" "" { target c++29 } }
+void
+bar ()
+{
+  foo ({ .a = 1 });            // { dg-error "call of overloaded 
'foo\\\(<brace-enclosed initializer list>\\\)' is ambiguous" "" { target c++29 
} }
+}                              // { dg-message "there are 2 candidates" "" { 
target c++29 } .-1 }
diff --git a/gcc/testsuite/g++.dg/cpp29/feat-cxx29.C 
b/gcc/testsuite/g++.dg/cpp29/feat-cxx29.C
index 2474e4340900..1d860c0ca14f 100644
--- a/gcc/testsuite/g++.dg/cpp29/feat-cxx29.C
+++ b/gcc/testsuite/g++.dg/cpp29/feat-cxx29.C
@@ -469,8 +469,8 @@
 
 #ifndef __cpp_designated_initializers
 #  error "__cpp_designated_initializers"
-#elif __cpp_designated_initializers != 201707
-#  error "__cpp_designated_initializers != 201707"
+#elif __cpp_designated_initializers != 202606
+#  error "__cpp_designated_initializers != 202606"
 #endif
 
 #ifndef __cpp_constexpr_in_decltype
diff --git a/gcc/testsuite/g++.dg/cpp2a/desig13.C 
b/gcc/testsuite/g++.dg/cpp2a/desig13.C
index a931e3486047..1da1b638682e 100644
--- a/gcc/testsuite/g++.dg/cpp2a/desig13.C
+++ b/gcc/testsuite/g++.dg/cpp2a/desig13.C
@@ -11,6 +11,7 @@ void
 baz ()
 {
   foo ({.d = 5, 6, .b = 2, 3});        // { dg-error "designator order for 
field 'S::b' does not match declaration order in 'S'" }
-                               // { dg-error "either all initializer clauses 
should be designated or none of them should be" "" { target c++20 } .-1 }
+                               // { dg-error "either all initializer clauses 
should be designated or none of them should be" "" { target { c++20 && 
c++26_down } } .-1 }
+                               // { dg-error "designated initializer clause 
should not be followed by non-designated" "" { target c++29 } .-2 }
   bar ({.b = 1, .a = 2});      // { dg-error "designator order for field 
'T::a' does not match declaration order in 'T'" }
 }
diff --git a/gcc/testsuite/g++.dg/cpp2a/desig2.C 
b/gcc/testsuite/g++.dg/cpp2a/desig2.C
index c993134fea0d..a10a1d2e6797 100644
--- a/gcc/testsuite/g++.dg/cpp2a/desig2.C
+++ b/gcc/testsuite/g++.dg/cpp2a/desig2.C
@@ -5,8 +5,10 @@ struct S { int a, b, c; };
 
 S a = { 1, 2, 3 };
 S b = { .a = 1, .b = 2, .c = 3 };
-S c = { 1, .b = 2, .c = 3 };   // { dg-error "either all initializer clauses 
should be designated or none of them should be" "" { target c++20 } }
-S d = { .a = 1, 2, 3 };                // { dg-error "either all initializer 
clauses should be designated or none of them should be" "" { target c++20 } }
+S c = { 1, .b = 2, .c = 3 };   // { dg-warning "either all initializer clauses 
should be designated or none of them should be" "" { target { c++20 && 
c++26_down } } }
+                               // { dg-error "last non-designated initializer 
clause does not appertain to a base class subobject" "" { target c++20 } .-1 }
+S d = { .a = 1, 2, 3 };                // { dg-error "either all initializer 
clauses should be designated or none of them should be" "" { target { c++20 && 
c++26_down } } }
+                               // { dg-error "designated initializer clause 
should not be followed by non-designated" "" { target c++29 } .-1 }
 S e = { .b = 1, .b = 2 };      // { dg-error "designator used multiple times 
in the same initializer list" }
 
 #if __cplusplus > 201103L
diff --git a/gcc/testsuite/g++.dg/cpp2a/desig20.C 
b/gcc/testsuite/g++.dg/cpp2a/desig20.C
index 0ceda7ccabdd..9faaf72deeb0 100644
--- a/gcc/testsuite/g++.dg/cpp2a/desig20.C
+++ b/gcc/testsuite/g++.dg/cpp2a/desig20.C
@@ -16,5 +16,5 @@ struct B : A {
 int main()
 {
   [[maybe_unused]] B b =
-  { .a = 10, .d = 42 };                // { dg-error "not a direct member" }
+  { .a = 10, .d = 42 };                // { dg-error "not a direct member" "" 
{ target c++26_down } }
 }
diff --git a/gcc/testsuite/g++.dg/ext/desig4.C 
b/gcc/testsuite/g++.dg/ext/desig4.C
index 9b92a6de2493..c431a10fd1e0 100644
--- a/gcc/testsuite/g++.dg/ext/desig4.C
+++ b/gcc/testsuite/g++.dg/ext/desig4.C
@@ -5,10 +5,11 @@ char g[] = { [7] = "abcd" };       // { dg-error 
"15:designator .7." }
 int a = { .foo = 6 };               // { dg-error "designator" }
 int b = { [0] = 1 };                // { dg-error "12:designator .0." }
 _Complex float c = { .foo = 0,  1 }; // { dg-error "designator" }
-                                    // { dg-error "either all initializer 
clauses should be designated or none of them should be" "" { target c++2a } .-1 
}
+                                    // { dg-error "either all initializer 
clauses should be designated or none of them should be" "" { target { c++20 && 
c++26_down } } .-1 }
+                                    // { dg-error "designated initializer 
clause should not be followed by non-designated" "" { target c++29 } .-2 }
 _Complex float d = { [0] = 0,  1 };  // { dg-error "23:designator .0." }
-                                    // { dg-error "either all initializer 
clauses should be designated or none of them should be" "" { target c++2a } .-1 
}
+                                    // { dg-error "either all initializer 
clauses should be designated or none of them should be" "" { target c++20 } .-1 
}
 _Complex float e = { 0, .foo = 1 };  // { dg-error "designator" }
-                                    // { dg-error "either all initializer 
clauses should be designated or none of them should be" "" { target c++2a } .-1 
}
+                                    // { dg-warning "either all initializer 
clauses should be designated or none of them should be" "" { target { c++20 && 
c++26_down } } .-1 }
 _Complex float f = { 0, [0] = 1 };   // { dg-error "26:designator .0." }
-                                    // { dg-error "either all initializer 
clauses should be designated or none of them should be" "" { target c++2a } .-1 
}
+                                    // { dg-error "either all initializer 
clauses should be designated or none of them should be" "" { target c++20 } .-1 
}
diff --git a/gcc/testsuite/g++.dg/parse/pr43765.C 
b/gcc/testsuite/g++.dg/parse/pr43765.C
index aa099a4d20be..acd0fbd8793a 100644
--- a/gcc/testsuite/g++.dg/parse/pr43765.C
+++ b/gcc/testsuite/g++.dg/parse/pr43765.C
@@ -10,8 +10,9 @@ const char *temp[] = {"607", "612", 0};
 
 SomeType vals[] =
     {
-        { 0, values : temp, },  // { dg-error "either all initializer clauses 
should be designated or none of them should be" "" { target c++2a } }
+       { 0, values : temp, },   // { dg-warning "either all initializer 
clauses should be designated or none of them should be" "" { target { c++20 && 
c++26_down } } }
         0
     };
 // (note the error below is on the wrong line)
-// { dg-error "initialization of flexible array member in a nested context" "" 
{ target *-*-* } .-2 }
+// { dg-error "initialization of flexible array member in a nested context" "" 
{ target c++17_down } .-2 }
+// { dg-error "last non-designated initializer clause does not appertain to a 
base class subobject" "" { target c++20 } .-3 }

Reply via email to