[clang] [clang][analyzer] Handle CXXParenInitListExpr alongside InitListExpr (PR #136041)
Fangyi Zhou via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 16 14:58:20 PDT 2025
https://github.com/fangyi-zhou created https://github.com/llvm/llvm-project/pull/136041
As reported in #135665, C++20 parenthesis initializer list expressions are not handled correctly and were causing crashes. This commit attempts to fix the issue by handing parenthesis initializer lists along side existing initializer lists.
>From 13d4ea6b0fb61ad27f596edbdf7daf20921f6989 Mon Sep 17 00:00:00 2001
From: Fangyi Zhou <me at fangyi.io>
Date: Wed, 16 Apr 2025 22:51:36 +0100
Subject: [PATCH] [clang][analyzer] Handle CXXParenInitListExpr alongside
InitListExpr
As reported in #135665, C++20 parenthesis initializer list expressions
are not handled correctly and were causing crashes. This commit attempts
to fix the issue by handing parenthesis initializer lists along side
existing initializer lists.
---
.../Checkers/DynamicTypePropagation.cpp | 10 ++++++----
clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp | 11 +++++++----
clang/test/Analysis/PR135665.cpp | 17 +++++++++++++++++
3 files changed, 30 insertions(+), 8 deletions(-)
create mode 100644 clang/test/Analysis/PR135665.cpp
diff --git a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
index a0bf776b11f53..6fad0601e87ca 100644
--- a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
@@ -379,10 +379,12 @@ void DynamicTypePropagation::checkPostCall(const CallEvent &Call,
// aggregates, and in such case no top-frame constructor will be called.
// Figure out if we need to do anything in this case.
// FIXME: Instead of relying on the ParentMap, we should have the
- // trigger-statement (InitListExpr in this case) available in this
- // callback, ideally as part of CallEvent.
- if (isa_and_nonnull<InitListExpr>(
- LCtx->getParentMap().getParent(Ctor->getOriginExpr())))
+ // trigger-statement (InitListExpr or CXXParenListInitExpr in this case)
+ // available in this callback, ideally as part of CallEvent.
+ const Stmt *Parent =
+ LCtx->getParentMap().getParent(Ctor->getOriginExpr());
+ if (isa_and_nonnull<InitListExpr>(Parent) ||
+ isa_and_nonnull<CXXParenListInitExpr>(Parent))
return;
recordFixedType(Target, cast<CXXConstructorDecl>(LCtx->getDecl()), C);
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index 7e878f922a939..914859861b948 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -644,9 +644,11 @@ void ExprEngine::handleConstructor(const Expr *E,
// FIXME: For now this code essentially bails out. We need to find the
// correct target region and set it.
// FIXME: Instead of relying on the ParentMap, we should have the
- // trigger-statement (InitListExpr in this case) passed down from CFG or
- // otherwise always available during construction.
- if (isa_and_nonnull<InitListExpr>(LCtx->getParentMap().getParent(E))) {
+ // trigger-statement (InitListExpr or CXXParenListInitExpr in this case)
+ // passed down from CFG or otherwise always available during construction.
+ if (isa_and_nonnull<InitListExpr>(LCtx->getParentMap().getParent(E)) ||
+ isa_and_nonnull<CXXParenListInitExpr>(
+ LCtx->getParentMap().getParent(E))) {
MemRegionManager &MRMgr = getSValBuilder().getRegionManager();
Target = loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx));
CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion = true;
@@ -1017,7 +1019,8 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
// values are properly placed inside the required region, however if an
// initializer list is used, this doesn't happen automatically.
auto *Init = CNE->getInitializer();
- bool isInitList = isa_and_nonnull<InitListExpr>(Init);
+ bool isInitList = isa_and_nonnull<InitListExpr>(Init) ||
+ isa_and_nonnull<CXXParenListInitExpr>(Init);
QualType ObjTy =
isInitList ? Init->getType() : CNE->getType()->getPointeeType();
diff --git a/clang/test/Analysis/PR135665.cpp b/clang/test/Analysis/PR135665.cpp
new file mode 100644
index 0000000000000..07848d9a590f5
--- /dev/null
+++ b/clang/test/Analysis/PR135665.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
+
+template<typename... F>
+struct overload : public F...
+{
+ using F::operator()...;
+};
+
+template<typename... F>
+overload(F&&...) -> overload<F...>;
+
+int main()
+{
+ const auto l = overload([](const int* i) {});
+
+ return 0;
+}
More information about the cfe-commits
mailing list