[clang] [analyzer] Fix crash destructing element of a sugared array type (PR #221220)
Arseniy Zaostrovnykh via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 7 08:47:14 PDT 2026
https://github.com/necto updated https://github.com/llvm/llvm-project/pull/221220
>From 3e0e868e95d1d9af10d2047eccc51c91c59261e0 Mon Sep 17 00:00:00 2001
From: Arseniy Zaostrovnykh <necto.ne at gmail.com>
Date: Fri, 4 Sep 2026 15:13:27 +0200
Subject: [PATCH 1/3] [analyzer] Fix crash destructuring element of a sugared
array type
ExprEngine::makeElementRegion falls short trying to determine the
element type of an array that involves a type aliasing a static array type.
This leads to a crash in ExprEngine::ProcessMemberDtor where it assumes
that element type is a CXXRecordDecl, while it is still a type alias to
a static array type.
getBaseElementType is the canonical way to desugar and peel off the
array dimensions.
--
CPP-8838
---
clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp | 7 ++-----
clang/test/Analysis/dtor-array.cpp | 7 +++++++
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index 9fb167ee2ea4a..bb1d98859e85e 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -107,11 +107,8 @@ SVal ExprEngine::makeElementRegion(ProgramStateRef State, SVal LValue,
SValBuilder &SVB = State->getStateManager().getSValBuilder();
ASTContext &Ctx = SVB.getContext();
- if (const ArrayType *AT = Ctx.getAsArrayType(Ty)) {
- while (AT) {
- Ty = AT->getElementType();
- AT = dyn_cast<ArrayType>(AT->getElementType());
- }
+ if (Ctx.getAsArrayType(Ty)) {
+ Ty = Ctx.getBaseElementType(Ty);
LValue = State->getLValue(Ty, SVB.makeArrayIndex(Idx), LValue);
IsArray = true;
}
diff --git a/clang/test/Analysis/dtor-array.cpp b/clang/test/Analysis/dtor-array.cpp
index 84a34af922516..1639c66c65869 100644
--- a/clang/test/Analysis/dtor-array.cpp
+++ b/clang/test/Analysis/dtor-array.cpp
@@ -326,6 +326,13 @@ void multidimensionalMember(){
clang_analyzer_eval(EvalOrderArr[3] == 0); // expected-warning {{TRUE}}
}
+void typedefMultidimensionalNoCrash(){
+ // The inner dimension is hidden behind a typedef, so the element type of the
+ // outer array is a TypedefType rather than a ConstantArrayType.
+ typedef EvalOrder EvalOrderRow[2];
+ EvalOrderRow arr[2]; // no-crash
+}
+
void *memset(void *, int, size_t);
void clang_analyzer_dumpElementCount(InlineDtor *);
>From 26c2231f74ea00f4fb48a5c8a0e2033f604fb8d4 Mon Sep 17 00:00:00 2001
From: Arseniy Zaostrovnykh <necto.ne at gmail.com>
Date: Mon, 7 Sep 2026 16:55:26 +0200
Subject: [PATCH 2/3] [NFC] Unsmell the code
---
clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index bb1d98859e85e..ba011794d9617 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -105,9 +105,8 @@ void ExprEngine::performTrivialCopy(ExplodedNodeSet &Dst, ExplodedNode *Pred,
SVal ExprEngine::makeElementRegion(ProgramStateRef State, SVal LValue,
QualType &Ty, bool &IsArray, unsigned Idx) {
SValBuilder &SVB = State->getStateManager().getSValBuilder();
- ASTContext &Ctx = SVB.getContext();
- if (Ctx.getAsArrayType(Ty)) {
+ if (ASTContext &Ctx = SVB.getContext(); Ctx.getAsArrayType(Ty)) {
Ty = Ctx.getBaseElementType(Ty);
LValue = State->getLValue(Ty, SVB.makeArrayIndex(Idx), LValue);
IsArray = true;
>From 4aac03ec7e05da530e2144caca03ff3c70cd27e8 Mon Sep 17 00:00:00 2001
From: Arseniy Zaostrovnykh <necto.ne at gmail.com>
Date: Mon, 7 Sep 2026 17:31:32 +0200
Subject: [PATCH 3/3] [NFC] Unsmell the code
---
clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index ba011794d9617..6118e029da0dd 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -106,7 +106,7 @@ SVal ExprEngine::makeElementRegion(ProgramStateRef State, SVal LValue,
QualType &Ty, bool &IsArray, unsigned Idx) {
SValBuilder &SVB = State->getStateManager().getSValBuilder();
- if (ASTContext &Ctx = SVB.getContext(); Ctx.getAsArrayType(Ty)) {
+ if (const ASTContext &Ctx = SVB.getContext(); Ctx.getAsArrayType(Ty)) {
Ty = Ctx.getBaseElementType(Ty);
LValue = State->getLValue(Ty, SVB.makeArrayIndex(Idx), LValue);
IsArray = true;
More information about the cfe-commits
mailing list