blob: a692462caf69b464c1a8dcec6e116e989912d844 [file] [log] [blame]
// 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 ();
}