--- gcc/testsuite/g++.dg/cpp26/aggr-init1.C.jj	2024-07-18 12:25:03.767375097 +0200
+++ gcc/testsuite/g++.dg/cpp26/aggr-init1.C	2024-07-18 14:27:48.324677997 +0200
@@ -0,0 +1,341 @@
+// P3106R1 - Clarifying rules for brace elision in aggregate initialization
+// Examples from C++26 [dcl.init.aggr]
+// { dg-do run }
+
+extern "C" void abort ();
+
+namespace N1 {
+#if __cpp_designated_initializers >= 201707L
+  struct C {
+    union {
+      int a;
+      const char* p;
+    };
+    int x;
+  } c = { .a = 1, .x = 3 };
+  constexpr C c2 = { .a = 1, .x = 3 };
+  static_assert (c2.a == 1 && c2.x == 3, "");
+#endif
+
+  bool
+  test ()
+  {
+#if __cpp_designated_initializers >= 201707L
+    return c.a == 1 && c.x == 3;
+#else
+    return true;
+#endif
+  }
+}
+
+namespace N2 {
+  struct A {
+    int x;
+    struct B {
+      int i;
+      int j;
+    } b;
+  } a = { 1, { 2, 3 } };
+
+#if __cplusplus >= 201703L
+  struct base1 { int b1, b2 = 42; };
+  struct base2 {
+    base2 () { b3 = 42; }
+    int b3;
+  };
+  struct derived : base1, base2 {
+    int d;
+  };
+
+  derived d1 { { 1, 2 }, {}, 4 };
+  derived d2 { {}, {}, 4 };
+#endif
+
+  bool
+  test ()
+  {
+    return a.x == 1 && a.b.i == 2 && a.b.j == 3
+#if __cplusplus >= 201703L
+	   && d1.b1 == 1 && d1.b2 == 2 && d1.b3 == 42 && d1.d == 4
+	   && d2.b1 == 0 && d2.b2 == 42 && d2.b3 == 42 && d2.d == 4
+#endif
+	   ;
+  }
+
+#if __cplusplus >= 201703L
+  constexpr A a2 = { 1, { 2, 3 } };
+  static_assert (a2.x == 1 && a2.b.i == 2 && a2.b.j == 3, "");
+
+  struct base3 {
+#if __cplusplus >= 202002L
+    constexpr base3 () { b3 = 42; }
+#else
+    constexpr base3 () : b3 (42) {}
+#endif
+    int b3;
+  };
+  struct derived2 : base1, base3 {
+    int d;
+  };
+  constexpr derived2 d3 { { 1, 2}, {}, 4};
+  constexpr derived2 d4 { {}, {}, 4 };
+  static_assert (d3.b1 == 1 && d3.b2 == 2 && d3.b3 == 42 && d3.d == 4, "");
+  static_assert (d4.b1 == 0 && d4.b2 == 42 && d4.b3 == 42 && d4.d == 4, "");
+#endif
+}
+
+namespace N3 {
+#if __cplusplus >= 201402L
+  struct S { int a; const char *b; int c; int d = b[a]; };
+  S ss = { 1, "asdf" };
+  constexpr S ss2 = { 1, "asdf" };
+  static_assert (ss2.a == 1 && ss2.b[0] == 'a' && ss2.b[3] == 'f' && ss2.c == 0 && ss2.d == 's', "");
+
+#if __cpp_designated_initializers >= 201707L
+  struct string { int s = -42; };
+  struct A {
+    string a;
+    int b = 42;
+    int c = -1;
+  };
+  static_assert (A { .c = 21 }.a.s == -42 && A { .c = 21 }.b == 42 && A { .c = 21 }.c == 21, "");
+#endif
+#endif
+
+  bool
+  test ()
+  {
+#if __cplusplus >= 201402L
+    return ss.a == 1 && __builtin_strcmp (ss.b, "asdf") == 0 && ss.c == 0 && ss.d == 's';
+#else
+    return true;
+#endif
+  }
+}
+
+namespace N4 {
+  int x[] = { 1, 3, 5 };
+
+  bool
+  test ()
+  {
+    return sizeof (x) == 3 * sizeof (int) && x[0] == 1 && x[1] == 3 && x[2] == 5;
+  }
+
+#if __cplusplus >= 201103L
+  constexpr int x2[] = { 1, 3, 5 };
+  static_assert (sizeof (x2) == 3 * sizeof (int)
+		 && x2[0] == 1 && x2[1] == 3 && x2[2] == 5, "");
+#endif
+}
+
+namespace N5 {
+  struct X { int i, j, k; };
+  X a[] = { 1, 2, 3, 4, 5, 6 };
+  X b[2] = { { 1, 2, 3 }, { 4, 5, 6 } };
+
+  bool
+  test ()
+  {
+    return sizeof (a) == sizeof (b) && __builtin_memcmp (a, b, sizeof (a)) == 0;
+  }
+
+#if __cplusplus >= 201103L
+  constexpr X a2[] = { 1, 2, 3, 4, 5, 6 };
+  constexpr X b2[2] = { { 1, 2, 3 }, { 4, 5, 6 } };
+  static_assert (sizeof (a2) == 2 * sizeof (X)
+		 && a2[0].i == 1 && a2[0].j == 2 && a2[0].k == 3
+		 && a2[1].i == 4 && a2[1].j == 5 && a2[1].k == 6, "");
+  static_assert (sizeof (b2) == 2 * sizeof (X)
+		 && b2[0].i == 1 && b2[0].j == 2 && b2[0].k == 3
+		 && b2[1].i == 4 && b2[1].j == 5 && b2[1].k == 6, "");
+#endif
+}
+
+namespace N7 {
+  struct A {
+    int i;
+    static int s;
+    int j;
+    int : 17;
+    int k;
+  } a = { 1, 2, 3 };
+
+  bool
+  test ()
+  {
+    return a.i == 1 && a.j == 2 && a.k == 3;
+  }
+
+#if __cplusplus >= 201103L
+  constexpr A a2 = { 1, 2, 3 };
+  static_assert (a2.i == 1 && a2.j == 2 && a2.k == 3, "");
+#endif
+}
+
+namespace N9 {
+  int x[2][2] = { 3, 1, 4, 2 };
+  float y[4][3] = {
+    { 1 }, { 2 }, { 3 }, { 4 }
+  };
+
+  bool
+  test ()
+  {
+    return x[0][0] == 3 && x[0][1] == 1 && x[1][0] == 4 && x[1][1] == 2
+	   && y[0][0] == 1.f && y[0][1] == 0.f && y[0][2] == 0.f
+	   && y[1][0] == 2.f && y[1][1] == 0.f && y[1][2] == 0.f
+	   && y[2][0] == 3.f && y[2][1] == 0.f && y[2][2] == 0.f
+           && y[3][0] == 4.f && y[3][1] == 0.f && y[3][2] == 0.f;
+  }
+
+#if __cplusplus >= 201103L
+  constexpr int x2[2][2] = { 3, 1, 4, 2 };
+  constexpr float y2[4][3] = {
+    { 1 }, { 2 }, { 3 }, { 4 }
+  };
+  static_assert (x2[0][0] == 3 && x2[0][1] == 1 && x2[1][0] == 4 && x2[1][1] == 2, "");
+  static_assert (y2[0][0] == 1.f && y2[0][1] == 0.f && y2[0][2] == 0.f, "");
+  static_assert (y2[1][0] == 2.f && y2[1][1] == 0.f && y2[1][2] == 0.f, "");
+  static_assert (y2[2][0] == 3.f && y2[2][1] == 0.f && y2[2][2] == 0.f, "");
+  static_assert (y2[3][0] == 4.f && y2[3][1] == 0.f && y2[3][2] == 0.f, "");
+#endif
+}
+
+namespace N10 {
+  struct S1 { int a, b; };
+  struct S2 { S1 s, t; };
+
+  S2 x[2] = { 1, 2, 3, 4, 5, 6, 7, 8 };
+  S2 y[2] = {
+    {
+      { 1, 2 },
+      { 3, 4 }
+    },
+    {
+      { 5, 6 },
+      { 7, 8 }
+    }
+  };
+
+  bool
+  test ()
+  {
+    return sizeof (x) == sizeof (y) && __builtin_memcmp (x, y, sizeof (x)) == 0;
+  }
+
+#if __cplusplus >= 201103L
+  constexpr S2 x2[2] = { 1, 2, 3, 4, 5, 6, 7, 8 };
+  constexpr S2 y2[2] = { { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } };
+  static_assert (x2[0].s.a == 1 && x2[0].s.b == 2 && x2[0].t.a == 3 && x2[0].t.b == 4, "");
+  static_assert (x2[1].s.a == 5 && x2[1].s.b == 6 && x2[1].t.a == 7 && x2[1].t.b == 8, "");
+  static_assert (y2[0].s.a == 1 && y2[0].s.b == 2 && y2[0].t.a == 3 && y2[0].t.b == 4, "");
+  static_assert (y2[1].s.a == 5 && y2[1].s.b == 6 && y2[1].t.a == 7 && y2[1].t.b == 8, "");
+#endif
+}
+
+namespace N12 {
+  float y[4][3] = {
+    { 1, 3, 5 },
+    { 2, 4, 6 },
+    { 3, 5, 7 },
+  };
+  float y2[4][3] = { 1, 3, 5, 2, 4, 6, 3, 5, 7 };
+
+  bool
+  test ()
+  {
+    for (int i = 0; i < 4; ++i)
+      for (int j = 0; j < 3; ++j)
+	if (y[i][j] != (i == 3 ? 0.f : (float) (i + 1 + j * 2))
+	    || y[i][j] != y2[i][j])
+	  return false;
+    return true;
+  }
+
+#if __cplusplus >= 201103L
+  constexpr float y3[4][3] = { { 1, 3, 5 }, { 2, 4, 6 }, { 3, 5, 7 }, };
+  constexpr float y4[4][3] = { 1, 3, 5, 2, 4, 6, 3, 5, 7 };
+  static_assert (y3[0][0] == 1.f && y3[0][1] == 3.f && y3[0][2] == 5.f, "");
+  static_assert (y3[1][0] == 2.f && y3[1][1] == 4.f && y3[1][2] == 6.f, "");
+  static_assert (y3[2][0] == 3.f && y3[2][1] == 5.f && y3[2][2] == 7.f, "");
+  static_assert (y3[3][0] == 0.f && y3[3][1] == 0.f && y3[3][2] == 0.f, "");
+  static_assert (y4[0][0] == 1.f && y4[0][1] == 3.f && y4[0][2] == 5.f, "");
+  static_assert (y4[1][0] == 2.f && y4[1][1] == 4.f && y4[1][2] == 6.f, "");
+  static_assert (y4[2][0] == 3.f && y4[2][1] == 5.f && y4[2][2] == 7.f, "");
+  static_assert (y4[3][0] == 0.f && y4[3][1] == 0.f && y4[3][2] == 0.f, "");
+#endif
+}
+
+namespace N13 {
+  bool
+  test ()
+  {
+    struct S { } s;
+    struct A {
+      S s1;
+      int i1;
+      S s2;
+      int i2;
+      S s3;
+      int i3;
+    } a = {
+      { },
+      0,
+      s,
+      0
+    };
+    return a.i1 == 0 && a.i2 == 0;
+  }
+}
+
+namespace N14 {
+  struct A {
+    int i;
+    operator int ();
+  };
+  struct B {
+    A a1, a2;
+    int z;
+  };
+  A a;
+  B b = { 4, a, a };
+  A::operator int () { return 42; }
+
+  bool
+  test ()
+  {
+    return b.a1.i == 4 && b.a2.i == 0 && b.z == 42;
+  }
+
+#if __cplusplus >= 201103L
+  struct A2 {
+    int i;
+    constexpr operator int () const { return 42; }
+  };
+  struct B2 {
+    A2 a1, a2;
+    int z;
+  };
+  constexpr A2 a2 = { 26 };
+  constexpr B2 b2 = { 4, a2, a2 };
+  static_assert (b2.a1.i == 4 && b2.a2.i == 26 && b2.z == 42, "");
+#endif
+}
+
+int
+main ()
+{
+  if (!N1::test ()
+      || !N2::test ()
+      || !N3::test ()
+      || !N4::test ()
+      || !N5::test ()
+      || !N7::test ()
+      || !N9::test ()
+      || !N10::test ()
+      || !N12::test ()
+      || !N13::test ()
+      || !N14::test ())
+    abort ();
+}
--- gcc/testsuite/g++.dg/cpp26/aggr-init2.C.jj	2024-07-18 13:03:47.980808005 +0200
+++ gcc/testsuite/g++.dg/cpp26/aggr-init2.C	2024-07-18 14:31:20.930947591 +0200
@@ -0,0 +1,67 @@
+// P3106R1 - Clarifying rules for brace elision in aggregate initialization
+// Examples from C++26 [dcl.init.aggr]
+// { dg-do compile }
+
+namespace N1 {
+#if __cpp_designated_initializers >= 201707L
+  struct C {
+    union {
+      int a;
+      const char* p;
+    };
+    int x;
+  };
+  constexpr C c2 = { .a = 42.0, .x = 3 };	// { dg-error "narrowing conversion of '4.2e\\\+1' from 'double' to 'int'" "" { target c++20 } }
+#endif
+}
+
+namespace N6 {
+#if __cplusplus >= 201103L
+  struct S {
+    int y[] = { 0 };	// { dg-error "ISO C\\\+\\\+ forbids flexible array member 'y'" "" { target c++11 } }
+			// { dg-error "flexible array member 'N6::S::y' in an otherwise empty 'struct N6::S' is a GCC extension" "" { target c++11 } .-1 }
+			// { dg-error "initializer for flexible array member 'int N6::S::y \\\[\\\]'" "" { target c++11 } .-2 }
+  };
+#endif
+}
+
+namespace N8 {
+#if __cplusplus >= 201402L
+  struct A;
+  extern A a;
+  struct A {
+    const A &a1 { A { a, a } };
+    const A &a2 { A { } };	// { dg-error "default member initializer for 'N8::A::a2' required before the end of its enclosing class" "" { target c++14 } }
+  };				// { dg-error "invalid initialization of reference of type 'const N8::A\\\&' from expression of type '<brace-enclosed initializer list>'" "" { target c++14 } .-1 }
+  A a { a, a };
+
+  struct B {
+    int n = B {}.n;		// { dg-error "default member initializer for 'N8::B::n' required before the end of its enclosing class" "" { target c++14 } }
+  };
+
+  struct C;
+  extern C c;
+  struct C {
+    const C &c1 { C { c, c } };
+    const C &c2 { C { c, c } };
+  };
+  C c { c, c };
+#endif
+}
+
+namespace N11 {
+  char cv[4] = { 'a', 's', 'd', 'f', 0 };	// { dg-error "too many initializers for 'char \\\[4\\\]'" }
+}
+
+namespace N15 {
+  union u { int a; const char* b; };
+  u a = { 1 };
+  u b = a;
+  u c = 1;                        // { dg-error "conversion from 'int' to non-scalar type 'N15::u' requested" }
+  u d = { 0, "asdf" };            // { dg-error "too many initializers for 'N15::u'" }
+  u e = { "asdf" };               // { dg-error "invalid conversion from 'const char\\\*' to 'int'" }
+#if __cpp_designated_initializers >= 201707L
+  u f = { .b = "asdf" };
+  u g = { .a = 1, .b = "asdf" };  // { dg-error "too many initializers for 'N15::u'" "" { target c++20 } }
+#endif
+}
