[clang] 746b8c4 - Basic support for flexible array members in constant evaluation.
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Mon Jul 13 16:58:03 PDT 2020
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}}
+}
More information about the cfe-commits
mailing list