bool ZeroInitialization(const Expr *E) {
const ConstantArrayType *CAT =
Info.Ctx.getAsConstantArrayType(E->getType());
- if (!CAT)
+ if (!CAT) {
+ if (const IncompleteArrayType *IAT =
+ Info.Ctx.getAsIncompleteArrayType(E->getType())) {
+ // We can be asked to zero-initialize a flexible array member; this
+ // is represented as an ImplicitValueInitExpr of incomplete array
+ // type. In this case, the array has zero elements.
+ Result = APValue(APValue::UninitArray(), 0, 0);
+ return true;
+ }
+ // FIXME: We could handle VLAs here.
return Error(E);
+ }
Result = APValue(APValue::UninitArray(), 0,
CAT->getSize().getZExtValue());
f3(a);
}
}
+
+namespace flexible_array {
+ struct A { int x; char arr[]; }; // expected-warning {{C99}} expected-note {{here}}
+ constexpr A a = {1};
+ static_assert(a.x == 1, "");
+ static_assert(&a.arr != nullptr, "");
+ static_assert(a.arr[0], ""); // expected-error {{constant expression}} expected-note {{array member without known bound}}
+ static_assert(a.arr[1], ""); // expected-error {{constant expression}} expected-note {{array member without known bound}}
+
+ constexpr A b[] = {{1}, {2}, {3}}; // expected-warning {{flexible array member}}
+ static_assert(b[0].x == 1, "");
+ static_assert(b[1].x == 2, "");
+ static_assert(b[2].x == 3, "");
+ static_assert(b[2].arr[0], ""); // expected-error {{constant expression}} expected-note {{array member without known bound}}
+
+ // If we ever start to accept this, we'll need to ensure we can
+ // constant-evaluate it properly.
+ constexpr A c = {1, 2, 3}; // expected-error {{initialization of flexible array member}}
+}