[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