[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
Thu Oct 22 00:54:03 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Sriraj2911
<details>
<summary>Changes</summary>
**Description**
Fixes an assertion failure in LValue::addUnsizedArray when constant evaluation encounters array subscripting on an invalid/redeclared object declaration.
**Root Cause**
Evaluating '&a[6]' on 'void a;' passes a Base object with void type into addUnsizedArray. Because void is neither a pointer nor an array type, it fails the assertion:
assert(!Base || getType(Base).getNonReferenceType()->isPointerType() || getType(Base).getNonReferenceType()->isArrayType());
**Fix**
Guarded addUnsizedArray to check for isInvalidDecl(), containsErrors(), and validated that BaseTy is an array or pointer type before updating the designator.
**Testing**
Added regression test clang/test/SemaCXX/225046.cpp and verified via llvm-lit.
---
Full diff: https://github.com/llvm/llvm-project/pull/234517.diff
2 Files Affected:
- (modified) clang/lib/AST/ExprConstant.cpp (+29)
- (added) clang/test/SemaCXX/225046.cpp (+10)
``````````diff
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 6d390032e2c71..17d3855f0d907 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -1538,7 +1538,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 0000000000000..98c22f8b1a569
--- /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
``````````
</details>
https://github.com/llvm/llvm-project/pull/234517
More information about the cfe-commits
mailing list