https://github.com/fangyi-zhou updated 
https://github.com/llvm/llvm-project/pull/136041

>From a0b769ee35df18418ed410e30ac6cdde9024a4f1 Mon Sep 17 00:00:00 2001
From: Fangyi Zhou <m...@fangyi.io>
Date: Wed, 16 Apr 2025 23:52:39 +0100
Subject: [PATCH 1/4] [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 ++++++----
 .../lib/StaticAnalyzer/Core/ExprEngineCXX.cpp | 11 +++++++----
 clang/test/Analysis/PR135665.cpp              | 19 +++++++++++++++++++
 3 files changed, 32 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..124b8c9b97b04
--- /dev/null
+++ b/clang/test/Analysis/PR135665.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_analyze_cc1 -std=c++20 -analyzer-checker=core -verify %s
+
+// expected-no-diagnostics
+
+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;
+}

>From 8b9159444418692b49b9eb4fb06bd5d9ee863354 Mon Sep 17 00:00:00 2001
From: Fangyi Zhou <m...@fangyi.io>
Date: Thu, 17 Apr 2025 17:43:07 +0100
Subject: [PATCH 2/4] Fix isa_and_nonnull calls

---
 .../lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp  | 6 ++----
 clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp             | 3 +--
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp 
b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
index 6fad0601e87ca..e58329817d7cd 100644
--- a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
@@ -381,10 +381,8 @@ void DynamicTypePropagation::checkPostCall(const CallEvent 
&Call,
         // FIXME: Instead of relying on the ParentMap, we should have the
         // 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))
+        if (isa_and_nonnull<InitListExpr, CXXParenListInitExpr>(
+                LCtx->getParentMap().getParent(Ctor->getOriginExpr())))
           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 914859861b948..7b0e24dbd5ee9 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -646,8 +646,7 @@ void ExprEngine::handleConstructor(const Expr *E,
     // FIXME: Instead of relying on the ParentMap, we should have the
     // 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>(
+    if (isa_and_nonnull<InitListExpr, CXXParenListInitExpr>(
             LCtx->getParentMap().getParent(E))) {
       MemRegionManager &MRMgr = getSValBuilder().getRegionManager();
       Target = loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx));

>From 553c116194a1661f43231f07346e17e8e31c9684 Mon Sep 17 00:00:00 2001
From: Fangyi Zhou <m...@fangyi.io>
Date: Thu, 17 Apr 2025 17:47:53 +0100
Subject: [PATCH 3/4] Add a release note entry

---
 clang/docs/ReleaseNotes.rst | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 0891fd058bb57..b52812a507bb6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -426,6 +426,8 @@ Bug Fixes in This Version
   using C++23 "deducing this" did not have a diagnostic location (#GH135522)
 
 - Fixed a crash when a ``friend`` function is redefined as deleted. (#GH135506)
+- Fixed a crash in clang analyzer when C++20 parenthesized initializer lists 
are
+  used. (#GH136041)
 
 Bug Fixes to Compiler Builtins
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

>From c5fcba3c3f8222eeaeba8f14206dab03dd6e6e79 Mon Sep 17 00:00:00 2001
From: Fangyi Zhou <m...@fangyi.io>
Date: Thu, 17 Apr 2025 17:48:53 +0100
Subject: [PATCH 4/4] Fix another call to isa_and_nonnull

---
 clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index 7b0e24dbd5ee9..92ce3fa2225c8 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -1018,8 +1018,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) ||
-                        isa_and_nonnull<CXXParenListInitExpr>(Init);
+      bool isInitList =
+          isa_and_nonnull<InitListExpr, CXXParenListInitExpr>(Init);
 
       QualType ObjTy =
           isInitList ? Init->getType() : CNE->getType()->getPointeeType();

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to