Skip to content

[clang][analyzer] Handle CXXParenInitListExpr alongside InitListExpr #139909

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: release/20.x
Choose a base branch
from

Conversation

steakhal
Copy link
Contributor

@steakhal steakhal commented May 14, 2025

[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 5dc9d55)

@steakhal steakhal added this to the LLVM 20.X Release milestone May 14, 2025
@steakhal steakhal requested review from tstellar and Xazax-hun May 14, 2025 14:33
@github-project-automation github-project-automation bot moved this to Needs Triage in LLVM Release Status May 14, 2025
@llvmbot llvmbot added the clang Clang issues not falling into any other category label May 14, 2025
@llvmbot
Copy link
Member

llvmbot commented May 14, 2025

@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-static-analyzer-1

Author: Balazs Benics (steakhal)

Changes

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 13d4ea6)


Full diff: https://github.com/llvm/llvm-project/pull/139909.diff

4 Files Affected:

  • (modified) clang/docs/ReleaseNotes.rst (+2)
  • (modified) clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp (+6-4)
  • (modified) clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (+7-4)
  • (added) clang/test/Analysis/PR135665.cpp (+17)
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;
+}

@steakhal
Copy link
Contributor Author

I already amended the patch to add this fix to the release notes of clang. That's the only change I made to the picked commit.

@github-project-automation github-project-automation bot moved this from Needs Triage to Needs Merge in LLVM Release Status May 14, 2025
@fangyi-zhou
Copy link
Contributor

I think you probably want to cherry-pick 5dc9d55 which addresses reviewer comments and fixes the tests.

As reported in llvm#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 5dc9d55)
@steakhal steakhal force-pushed the bb/backport-overloaded-lambda-crash-fix branch from dc4c960 to a7e4819 Compare May 15, 2025 07:40
@steakhal
Copy link
Contributor Author

I think you probably want to cherry-pick 5dc9d55 which addresses reviewer comments and fixes the tests.

Correct. Thank you! I've updated the PR accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:static analyzer clang Clang issues not falling into any other category release:backport
Projects
Status: Needs Merge
Development

Successfully merging this pull request may close these issues.

4 participants