Author: Timm Baeder
Date: 2025-05-09T09:03:20+02:00
New Revision: d35ad58859c97521edab7b2eddfa9fe6838b9a5e

URL: 
https://github.com/llvm/llvm-project/commit/d35ad58859c97521edab7b2eddfa9fe6838b9a5e
DIFF: 
https://github.com/llvm/llvm-project/commit/d35ad58859c97521edab7b2eddfa9fe6838b9a5e.diff

LOG: [clang][ExprConst] Check for array size of initlists (#138673)

Fixes #138653

Added: 
    

Modified: 
    clang/lib/AST/ExprConstant.cpp
    clang/test/SemaCXX/constant-expression-cxx2a.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 500d43accb082..13eeffca04411 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -11788,6 +11788,11 @@ bool 
ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
   LLVM_DEBUG(llvm::dbgs() << "The number of elements to initialize: "
                           << NumEltsToInit << ".\n");
 
+  if (!Info.CheckArraySize(ExprToVisit->getExprLoc(),
+                           CAT->getNumAddressingBits(Info.Ctx), NumEltsToInit,
+                           /*Diag=*/true))
+    return false;
+
   Result = APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
 
   // If the array was previously zero-initialized, preserve the
@@ -11919,6 +11924,9 @@ bool ArrayExprEvaluator::VisitCXXConstructExpr(const 
CXXConstructExpr *E,
   if (const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(Type)) {
     unsigned FinalSize = CAT->getZExtSize();
 
+    if (!CheckArraySize(Info, CAT, E->getExprLoc()))
+      return false;
+
     // Preserve the array filler if we had prior zero-initialization.
     APValue Filler =
       HadZeroInit && Value->hasArrayFiller() ? Value->getArrayFiller()

diff  --git a/clang/test/SemaCXX/constant-expression-cxx2a.cpp 
b/clang/test/SemaCXX/constant-expression-cxx2a.cpp
index 85720606fe9de..3b58ebc6aaa1e 100644
--- a/clang/test/SemaCXX/constant-expression-cxx2a.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx2a.cpp
@@ -1497,3 +1497,45 @@ namespace GH67317 {
                               // expected-note {{subobject of type 'const 
unsigned char' is not initialized}}
     __builtin_bit_cast(unsigned char, *new char[3][1]);
 };
+
+namespace GH138653 {
+  constexpr unsigned kNumberOfIterations = 2000000;
+  constexpr unsigned kThreadsNumber = 2 * 8 * 1024;
+
+  /// Large array initialized by Paren/InitListExpr.
+  template <typename T, unsigned long S>
+  struct array1 {
+    using AT = T[S];
+    AT Data{};
+    constexpr array1() : Data(T()) {} // expected-note {{cannot allocate 
array}}
+  };
+
+  /// And initialized by a CXXConstructExpr.
+  template <typename T, unsigned long S>
+  struct array2 {
+    using AT = T[S];
+    AT Data;
+    constexpr array2() {} // expected-note {{cannot allocate array}}
+  };
+
+  template <typename T>
+  class A{};
+  int main() {
+      array1<A<short*>, kThreadsNumber * kNumberOfIterations> futures1{};
+      array2<A<short*>, kThreadsNumber * kNumberOfIterations> futures2{};
+  }
+
+  constexpr int CE1() {
+    array1<A<short*>, kThreadsNumber * kNumberOfIterations> futures1{}; // 
expected-note {{in call to}}
+    return 1;
+  }
+  static_assert(CE1() == 1); // expected-error {{not an integral constant 
expression}} \
+                             // expected-note {{in call to}}
+
+  constexpr int CE2() {
+    array2<A<short*>, kThreadsNumber * kNumberOfIterations> futures2{}; // 
expected-note {{in call to}}
+    return 1;
+  }
+  static_assert(CE2() == 1); // expected-error {{not an integral constant 
expression}} \
+                             // expected-note {{in call to}}
+}


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to