[clang] [analyzer] Fix crash destructuring element of a sugared array type (PR #221220)
Arseniy Zaostrovnykh via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 4 06:16:16 PDT 2026
https://github.com/necto created https://github.com/llvm/llvm-project/pull/221220
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
>From d0d2309d5ff522e6c7785277d3061a001ac2347d 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] [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 | 11 +++++++++++
2 files changed, 13 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..6222724a74db1 100644
--- a/clang/test/Analysis/dtor-array.cpp
+++ b/clang/test/Analysis/dtor-array.cpp
@@ -326,6 +326,17 @@ void multidimensionalMember(){
clang_analyzer_eval(EvalOrderArr[3] == 0); // expected-warning {{TRUE}}
}
+// 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];
+
+struct TypedefMultiWrapper {
+ EvalOrderRow arr[2];
+};
+
+void typedefMultidimensionalPrep(){
+ EvalOrderRow arr[2]; // no-crash
+}
void *memset(void *, int, size_t);
void clang_analyzer_dumpElementCount(InlineDtor *);
More information about the cfe-commits
mailing list