1 // RUN: %clang_cc1 -std=c++2c -verify %s 2 3 namespace ex1 { 4 struct C { 5 union { 6 int a; 7 const char* p; 8 }; 9 int x; 10 }; 11 12 constexpr C c = { .a = 1, .x = 3 }; 13 static_assert(c.a == 1); 14 static_assert(c.x == 3); 15 16 static constexpr C c2 = { .a = 1.0, .x = 3 }; 17 // expected-error@-1 {{type 'double' cannot be narrowed to 'int' in initializer list}} 18 // expected-note@-2 {{insert an explicit cast to silence this issue}} 19 } // namespace ex1 20 21 namespace ex2 { 22 struct A { 23 int x; 24 struct B { 25 int i; 26 int j; 27 } b; 28 }; 29 30 constexpr A a = { 1, { 2, 3 } }; 31 static_assert(a.x == 1); 32 static_assert(a.b.i == 2); 33 static_assert(a.b.j == 3); 34 35 struct base1 { int b1, b2 = 42; }; 36 struct base2 { base2ex2::base237 constexpr base2() { 38 b3 = 43; 39 } 40 int b3; 41 }; 42 struct derived : base1, base2 { 43 int d; 44 }; 45 46 constexpr derived d1{{1, 2}, {}, 4}; 47 static_assert(d1.b1 == 1); 48 static_assert(d1.b2 == 2); 49 static_assert(d1.b3 == 43); 50 static_assert(d1.d == 4); 51 52 constexpr derived d2{{}, {}, 4}; 53 static_assert(d2.b1 == 0); 54 static_assert(d2.b2 == 42); 55 static_assert(d2.b3 == 43); 56 static_assert(d2.d == 4); 57 } // namespace ex2 58 59 namespace ex3 { 60 struct S { 61 int a; 62 const char* b; 63 int c; 64 int d = b[a]; 65 }; 66 67 constexpr S ss = { 1, "asdf" }; 68 static_assert(ss.a == 1); 69 static_assert(__builtin_strcmp(ss.b, "asdf") == 0); 70 static_assert(ss.c == int{}); 71 static_assert(ss.d == ss.b[ss.a]); 72 73 struct string { 74 int d = 43; 75 }; 76 77 struct A { 78 string a; 79 int b = 42; 80 int c = -1; 81 }; 82 83 constexpr A a{.c = 21}; 84 static_assert(a.a.d == string{}.d); 85 static_assert(a.b == 42); 86 static_assert(a.c == 21); 87 } // namespace ex3 88 89 namespace ex4 { 90 int x[] = { 1, 3, 5 }; 91 static_assert(sizeof(x) / sizeof(int) == 3); 92 } // namespace ex4 93 94 namespace ex5 { 95 struct X { int i, j, k; }; 96 97 constexpr X a[] = { 1, 2, 3, 4, 5, 6 }; 98 constexpr X b[2] = { { 1, 2, 3 }, { 4, 5, 6 } }; 99 static_assert(sizeof(a) == sizeof(b)); 100 static_assert(a[0].i == b[0].i); 101 static_assert(a[0].j == b[0].j); 102 static_assert(a[0].k == b[0].k); 103 static_assert(a[1].i == b[1].i); 104 static_assert(a[1].j == b[1].j); 105 static_assert(a[1].k == b[1].k); 106 } // namespace ex5 107 108 namespace ex6 { 109 struct S { 110 int y[] = { 0 }; 111 // expected-error@-1 {{array bound cannot be deduced from a default member initializer}} 112 }; 113 } // namespace ex6 114 115 namespace ex7 { 116 struct A { 117 int i; 118 static int s; 119 int j; 120 int :17; 121 int k; 122 }; 123 124 constexpr A a = { 1, 2, 3 }; 125 static_assert(a.i == 1); 126 static_assert(a.j == 2); 127 static_assert(a.k == 3); 128 } // namespace ex7 129 130 namespace ex8 { 131 struct A; 132 extern A a; 133 struct A { 134 const A& a1 { A{a,a} }; 135 const A& a2 { A{} }; 136 // expected-error@-1 {{default member initializer for 'a2' needed within definition of enclosing class 'A' outside of member functions}} 137 // expected-note@-2 {{default member initializer declared here}} 138 }; 139 A a{a,a}; 140 141 struct B { 142 int n = B{}.n; 143 // expected-error@-1 {{default member initializer for 'n' needed within definition of enclosing class 'B' outside of member functions}} 144 // expected-note@-2 {{default member initializer declared here}} 145 }; 146 } // namespace ex8 147 148 namespace ex9 { 149 constexpr int x[2][2] = { 3, 1, 4, 2 }; 150 static_assert(x[0][0] == 3); 151 static_assert(x[0][1] == 1); 152 static_assert(x[1][0] == 4); 153 static_assert(x[1][1] == 2); 154 155 constexpr float y[4][3] = { 156 { 1 }, { 2 }, { 3 }, { 4 } 157 }; 158 static_assert(y[0][0] == 1); 159 static_assert(y[0][1] == 0); 160 static_assert(y[0][2] == 0); 161 static_assert(y[1][0] == 2); 162 static_assert(y[1][1] == 0); 163 static_assert(y[1][2] == 0); 164 static_assert(y[2][0] == 3); 165 static_assert(y[2][1] == 0); 166 static_assert(y[2][2] == 0); 167 static_assert(y[3][0] == 4); 168 static_assert(y[3][1] == 0); 169 static_assert(y[3][2] == 0); 170 } // namespace ex9 171 172 namespace ex10 { 173 struct S1 { int a, b; }; 174 struct S2 { S1 s, t; }; 175 176 constexpr S2 x[2] = { 1, 2, 3, 4, 5, 6, 7, 8 }; 177 constexpr S2 y[2] = { 178 { 179 { 1, 2 }, 180 { 3, 4 } 181 }, 182 { 183 { 5, 6 }, 184 { 7, 8 } 185 } 186 }; 187 static_assert(x[0].s.a == 1); 188 static_assert(x[0].s.b == 2); 189 static_assert(x[0].t.a == 3); 190 static_assert(x[0].t.b == 4); 191 static_assert(x[1].s.a == 5); 192 static_assert(x[1].s.b == 6); 193 static_assert(x[1].t.a == 7); 194 static_assert(x[1].t.b == 8); 195 } // namespace ex10 196 197 namespace ex11 { 198 char cv[4] = { 'a', 's', 'd', 'f', 0 }; 199 // expected-error@-1 {{excess elements in array initializer}} 200 } // namespace ex11 201 202 namespace ex12 { 203 constexpr float y[4][3] = { 204 { 1, 3, 5 }, 205 { 2, 4, 6 }, 206 { 3, 5, 7 }, 207 }; 208 static_assert(y[0][0] == 1); 209 static_assert(y[0][1] == 3); 210 static_assert(y[0][2] == 5); 211 static_assert(y[1][0] == 2); 212 static_assert(y[1][1] == 4); 213 static_assert(y[1][2] == 6); 214 static_assert(y[2][0] == 3); 215 static_assert(y[2][1] == 5); 216 static_assert(y[2][2] == 7); 217 static_assert(y[3][0] == 0.0); 218 static_assert(y[3][1] == 0.0); 219 static_assert(y[3][2] == 0.0); 220 221 constexpr float z[4][3] = { 222 1, 3, 5, 2, 4, 6, 3, 5, 7 223 }; 224 static_assert(z[0][0] == 1); 225 static_assert(z[0][1] == 3); 226 static_assert(z[0][2] == 5); 227 static_assert(z[1][0] == 2); 228 static_assert(z[1][1] == 4); 229 static_assert(z[1][2] == 6); 230 static_assert(z[2][0] == 3); 231 static_assert(z[2][1] == 5); 232 static_assert(z[2][2] == 7); 233 static_assert(z[3][0] == 0.0); 234 static_assert(z[3][1] == 0.0); 235 static_assert(z[3][2] == 0.0); 236 } // namespace ex12 237 238 namespace ex13 { 239 struct S { } s; 240 struct A { 241 S s1; 242 int i1; 243 S s2; 244 int i2; 245 S s3; 246 int i3; 247 } a = { 248 { }, // Required initialization 249 0, 250 s, // Required initialization 251 0 252 }; // Initialization not required for A::s3 because A::i3 is also not initialized 253 } // namespace ex13 254 255 namespace ex14 { 256 struct A { 257 int i; operator intex14::A258 constexpr operator int() const { return 42; }; 259 }; 260 struct B { 261 A a1, a2; 262 int z; 263 }; 264 constexpr A a{}; 265 constexpr B b = { 4, a, a }; 266 static_assert(b.a1.i == 4); 267 static_assert(b.a2.i == a.i); 268 static_assert(b.z == a.operator int()); 269 } // namespace ex14 270 271 namespace ex15 { 272 union u { // #ex15-u 273 int a; 274 const char* b; 275 }; 276 277 u a = { 1 }; 278 u b = a; 279 u c = 1; 280 // expected-error@-1 {{no viable conversion from 'int' to 'u'}} 281 // expected-note@#ex15-u {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const u &' for 1st argument}} 282 // expected-note@#ex15-u {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to 'u &&' for 1st argument}} 283 u d = { 0, "asdf" }; 284 // expected-error@-1 {{excess elements in union initializer}} 285 u e = { "asdf" }; 286 // expected-error@-1 {{cannot initialize a member subobject of type 'int' with an lvalue of type 'const char[5]'}} 287 u f = { .b = "asdf" }; 288 u g = { 289 .a = 1, // #ex15-g-a 290 .b = "asdf" 291 // expected-error@-1 {{initializer partially overrides prior initialization of this subobject}} 292 // expected-note@#ex15-g-a {{previous initialization is here}} 293 }; 294 } // namespace ex15 295