[clang] [clang][AST] Fix assertion crash in LValue::addUnsizedArray on invalid base type (#225046) (PR #234517)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Oct 25 23:39:25 PDT 2026
https://github.com/Sriraj2911 updated https://github.com/llvm/llvm-project/pull/234517
>From 97ccc16da3f27895e974f1054b5e63f2e5780649 Mon Sep 17 00:00:00 2001
From: Sriraj2911 <cs24btech11066 at iith.ac.in>
Date: Thu, 22 Oct 2026 13:19:00 +0530
Subject: [PATCH 1/2] [clang][AST] Fix assertion crash in
LValue::addUnsizedArray on invalid base type
When evaluating array subscript designators on an invalid or redeclared
declaration (such as evaluating on ),
can receive a Base object whose type is neither an array nor a pointer.
This triggered an assertion failure at ExprConstant.cpp:1542.
This patch adds safety checks for invalid declarations, error-containing types, and non-pointer/non-array base types before updating the designator, safely marking the designator as invalid instead of crashing.
Fixes #225046
---
clang/lib/AST/ExprConstant.cpp | 29 +++++++++++++++++++++++++++++
clang/test/SemaCXX/225046.cpp | 10 ++++++++++
2 files changed, 39 insertions(+)
create mode 100644 clang/test/SemaCXX/225046.cpp
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 3762bc83c779b0..50d2a9f17093bb 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -1540,7 +1540,36 @@ namespace {
Designator.setInvalid();
return;
}
+
+ if(Base){
+ // Mark invalid and return early if Base points to an invalid decl
+ if(const auto *VD = Base.dyn_cast<const ValueDecl *>()){
+ if(VD->isInvalidDecl()){
+ Designator.setInvalid();
+ return;
+ }
+ }
+ // Mark invalid and return early if Base points to an invalid type
+ QualType BaseTy = getType(Base).getNonReferenceType();
+ if(BaseTy.isNull() || BaseTy->containsErrors() || (!BaseTy->isPointerType() && !BaseTy->isArrayType())){
+ Designator.setInvalid();
+ return;
+ }
+ }
+
if (checkSubobject(Info, E, CSK_ArrayToPointer)) {
+ /*
+ When a user writes invalid C++ code (e.g., declaring a
+ variable as void and then illegally re-declaring/indexing
+ it as an array), the AST node representing Base ends up
+ with an invalid or unexpected type structure.
+ => getType(Base) does not fulfill either conditions, causing
+ the assert statement to fail and crash the compiler.
+ */
+ /*
+ To get a clean error, add a check before entering the above
+ if clause
+ */
assert(!Base || getType(Base).getNonReferenceType()->isPointerType() ||
getType(Base).getNonReferenceType()->isArrayType());
Designator.FirstEntryIsAnUnsizedArray = true;
diff --git a/clang/test/SemaCXX/225046.cpp b/clang/test/SemaCXX/225046.cpp
new file mode 100644
index 00000000000000..98c22f8b1a5691
--- /dev/null
+++ b/clang/test/SemaCXX/225046.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void a; // expected-error {{variable has incomplete type 'void'}}
+extern int a[];
+
+void test() {
+ // Force constant evaluation of &a[6].
+ // Before the fix this asserted in LValue::addUnsizedArray.
+ (void)__builtin_constant_p(&a[6]);
+}
\ No newline at end of file
>From 5fb4409de2c3a93b58cad369e373ad783c5fa8c5 Mon Sep 17 00:00:00 2001
From: Sriraj2911 <cs24btech11066 at iith.ac.in>
Date: Mon, 26 Oct 2026 12:05:55 +0530
Subject: [PATCH 2/2] [clang][AST] Fix array subscript constant evaluation
assertion (#225046)
---
clang/lib/AST/ExprConstant.cpp | 21 +++++++++------------
1 file changed, 9 insertions(+), 12 deletions(-)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 50d2a9f17093bb..cdfd3a53f76ffe 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -1558,18 +1558,15 @@ namespace {
}
if (checkSubobject(Info, E, CSK_ArrayToPointer)) {
- /*
- When a user writes invalid C++ code (e.g., declaring a
- variable as void and then illegally re-declaring/indexing
- it as an array), the AST node representing Base ends up
- with an invalid or unexpected type structure.
- => getType(Base) does not fulfill either conditions, causing
- the assert statement to fail and crash the compiler.
- */
- /*
- To get a clean error, add a check before entering the above
- if clause
- */
+ // When a user writes invalid C++ code (e.g., declaring a
+ // variable as void and then illegally re-declaring/indexing
+ // it as an array), the AST node representing Base ends up
+ // with an invalid or unexpected type structure.
+ // => getType(Base) does not fulfill either conditions, causing
+ // the assert statement to fail and crash the compiler.
+
+ // To get a clean error, add a check before entering the above
+ // if-clause
assert(!Base || getType(Base).getNonReferenceType()->isPointerType() ||
getType(Base).getNonReferenceType()->isArrayType());
Designator.FirstEntryIsAnUnsizedArray = true;
More information about the cfe-commits
mailing list