[llvm-branch-commits] [clang] [clang][analyzer] Handle CXXParenInitListExpr alongside InitListExpr (PR #139909)
Balazs Benics via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed May 14 07:34:05 PDT 2025
https://github.com/steakhal created https://github.com/llvm/llvm-project/pull/139909
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.
(cherry picked from commit 13d4ea6b0fb61ad27f596edbdf7daf20921f6989)
>From dc4c960f515890ca2cbf2ea944b5c38249741165 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.
(cherry picked from commit 13d4ea6b0fb61ad27f596edbdf7daf20921f6989)
---
clang/docs/ReleaseNotes.rst | 2 ++
.../Checkers/DynamicTypePropagation.cpp | 10 ++++++----
clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp | 11 +++++++----
clang/test/Analysis/PR135665.cpp | 17 +++++++++++++++++
4 files changed, 32 insertions(+), 8 deletions(-)
create mode 100644 clang/test/Analysis/PR135665.cpp
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 47ef2f80ac3f2..ffc46d9d75b68 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1467,6 +1467,8 @@ Crash and bug fixes
- The ``unix.BlockInCriticalSection`` now recognizes the ``lock()`` member function
as expected, even if it's inherited from a base class. Fixes (#GH104241).
+- Fixed a crash when using the overloaded lambda pattern. Fixes (#GH135665, #139789).
+
Improvements
^^^^^^^^^^^^
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 f7020da2e6da2..cf7a4f9b12048 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -637,9 +637,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;
@@ -1010,7 +1012,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 llvm-branch-commits
mailing list