diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index a4dc0ccad1e0f..d20c2382b6ac1 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -9929,8 +9929,18 @@ namespace { 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()); diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp index 78e9fef96c8da..b69bcb2fef9d0 100644 --- a/clang/test/SemaCXX/constant-expression-cxx11.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp @@ -2322,3 +2322,22 @@ namespace array_size { 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}} +}