[clang] d35ad58 - [clang][ExprConst] Check for array size of initlists (#138673)
via cfe-commits
cfe-commits at lists.llvm.org
Fri May 9 00:03:23 PDT 2025
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}}
+}
More information about the cfe-commits
mailing list