Author: Richard Smith Date: 2020-07-13T16:57:53-07:00 New Revision: 746b8c400bd3f975b49f4092aa6ecd30ade7cfa5
URL: https://github.com/llvm/llvm-project/commit/746b8c400bd3f975b49f4092aa6ecd30ade7cfa5 DIFF: https://github.com/llvm/llvm-project/commit/746b8c400bd3f975b49f4092aa6ecd30ade7cfa5.diff LOG: Basic support for flexible array members in constant evaluation. We don't allow runtime-sized flexible array members, nor initialization of flexible array members, but it seems reasonable to support the most basic case where the flexible array member is empty. Added: Modified: clang/lib/AST/ExprConstant.cpp clang/test/SemaCXX/constant-expression-cxx11.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index a4dc0ccad1e0..d20c2382b6ac 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 78e9fef96c8d..b69bcb2fef9d 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}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits