[clang] [clang] Fix crash constant-evaluating large arrays with initializer list or string literal (PR #229556)
Krisitan Erik Olsen via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 12 12:57:16 PDT 2026
https://github.com/Kristianerik updated https://github.com/llvm/llvm-project/pull/229556
>From 9b63c4ddbd15f0b8f1a71523dfb9e24e37da078b Mon Sep 17 00:00:00 2001
From: Kristianerik <kristian.erik at outlook.com>
Date: Tue, 6 Oct 2026 13:23:50 -0700
Subject: [PATCH 1/2] [clang] Fix crash constant-evaluating large arrays with
initializer list or string literal
---
clang/lib/AST/ExprConstant.cpp | 17 +++++++++++++++--
clang/test/Sema/gh227533.c | 8 ++++++++
2 files changed, 23 insertions(+), 2 deletions(-)
create mode 100644 clang/test/Sema/gh227533.c
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 34c3e39807c7f..2e0fcc523f0c3 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -15627,10 +15627,17 @@ namespace {
bool VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E);
bool VisitCXXConstructExpr(const CXXConstructExpr *E);
bool VisitCXXConstructExpr(const CXXConstructExpr *E,
- const LValue &Subobject,
- APValue *Value, QualType Type);
+ const LValue &Subobject, APValue *Value,
+ QualType Type);
bool VisitStringLiteral(const StringLiteral *E,
QualType AllocType = QualType()) {
+ const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
+ AllocType.isNull() ? E->getType() : AllocType);
+ if (CAT->getZExtSize() > std::numeric_limits<unsigned>::max()) {
+ Info.FFDiag(E->getExprLoc(), diag::note_constexpr_new_too_large)
+ << CAT->getZExtSize();
+ return false;
+ }
expandStringLiteral(Info, E, Result, AllocType);
return true;
}
@@ -15770,6 +15777,12 @@ bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
bool Success = true;
+ if (CAT->getZExtSize() > std::numeric_limits<unsigned>::max()) {
+ Info.FFDiag(ExprToVisit->getExprLoc(), diag::note_constexpr_new_too_large)
+ << CAT->getZExtSize();
+ return false;
+ }
+
unsigned NumEltsToInit = Args.size();
unsigned NumElts = CAT->getZExtSize();
diff --git a/clang/test/Sema/gh227533.c b/clang/test/Sema/gh227533.c
new file mode 100644
index 0000000000000..3281b7c20d403
--- /dev/null
+++ b/clang/test/Sema/gh227533.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+const char a[4294967296] = {0};
+int b(void) { return a[1]; }
+
+const char c[4294967296] = "x";
+int d(void) { return c[1]; }
>From dd565d3632ddf03787ef58a9bb2f6f1161b3d640 Mon Sep 17 00:00:00 2001
From: Kristianerik <kristian.erik at outlook.com>
Date: Mon, 12 Oct 2026 12:55:52 -0700
Subject: [PATCH 2/2] fixup! Centralize overflow check in EvaluateArray and
revert formatting change
---
clang/lib/AST/ExprConstant.cpp | 20 +++++++-------------
1 file changed, 7 insertions(+), 13 deletions(-)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 2e0fcc523f0c3..9ce52b0b0cc7e 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -15631,13 +15631,6 @@ namespace {
QualType Type);
bool VisitStringLiteral(const StringLiteral *E,
QualType AllocType = QualType()) {
- const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
- AllocType.isNull() ? E->getType() : AllocType);
- if (CAT->getZExtSize() > std::numeric_limits<unsigned>::max()) {
- Info.FFDiag(E->getExprLoc(), diag::note_constexpr_new_too_large)
- << CAT->getZExtSize();
- return false;
- }
expandStringLiteral(Info, E, Result, AllocType);
return true;
}
@@ -15655,6 +15648,13 @@ static bool EvaluateArray(const Expr *E, const LValue &This,
assert(!E->isValueDependent());
assert(E->isPRValue() && E->getType()->isArrayType() &&
"not an array prvalue");
+ if (const auto *CAT = Info.Ctx.getAsConstantArrayType(E->getType())) {
+ if (CAT->getZExtSize() > std::numeric_limits<unsigned>::max()) {
+ Info.FFDiag(E->getExprLoc(), diag::note_constexpr_new_too_large)
+ << CAT->getZExtSize();
+ return false;
+ }
+ }
return ArrayExprEvaluator(Info, This, Result).Visit(E);
}
@@ -15777,12 +15777,6 @@ bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
bool Success = true;
- if (CAT->getZExtSize() > std::numeric_limits<unsigned>::max()) {
- Info.FFDiag(ExprToVisit->getExprLoc(), diag::note_constexpr_new_too_large)
- << CAT->getZExtSize();
- return false;
- }
-
unsigned NumEltsToInit = Args.size();
unsigned NumElts = CAT->getZExtSize();
More information about the cfe-commits
mailing list