[clang] b4e3e3a - [analyzer] Fix a crash on copy elided initialized lambda captures

via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 12 15:22:29 PDT 2022


Author: isuckatcs
Date: 2022-08-13T00:22:01+02:00
New Revision: b4e3e3a3eb775df947f10212c461307592a13de0

URL: https://github.com/llvm/llvm-project/commit/b4e3e3a3eb775df947f10212c461307592a13de0
DIFF: https://github.com/llvm/llvm-project/commit/b4e3e3a3eb775df947f10212c461307592a13de0.diff

LOG: [analyzer] Fix a crash on copy elided initialized lambda captures

Inside `ExprEngine::VisitLambdaExpr()` we wasn't prepared for a
copy elided initialized capture's `InitExpr`. This patch teaches
the analyzer how to handle such situation.

Differential Revision: https://reviews.llvm.org/D131784

Added: 
    

Modified: 
    clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
    clang/test/Analysis/lambdas.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index 5801401ad3c4b..d1b7ef7806ba7 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -1143,7 +1143,9 @@ void ExprEngine::VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred,
 
     SVal InitVal;
     if (!FieldForCapture->hasCapturedVLAType()) {
-      Expr *InitExpr = *i;
+      const Expr *InitExpr = *i;
+
+      assert(InitExpr && "Capture missing initialization expression");
 
       if (const auto AILE = dyn_cast<ArrayInitLoopExpr>(InitExpr)) {
         // If the AILE initializes a POD array, we need to keep it as the
@@ -1152,7 +1154,12 @@ void ExprEngine::VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred,
           InitExpr = AILE->getSubExpr();
       }
 
-      assert(InitExpr && "Capture missing initialization expression");
+      // With C++17 copy elision this can happen.
+      if (const auto *FC = dyn_cast<CXXFunctionalCastExpr>(InitExpr))
+        InitExpr = FC->getSubExpr();
+
+      assert(InitExpr &&
+             "Extracted capture initialization expression is missing");
 
       if (dyn_cast<CXXConstructExpr>(InitExpr)) {
         InitVal = *getObjectUnderConstruction(State, {LE, Idx}, LocCtxt);

diff  --git a/clang/test/Analysis/lambdas.cpp b/clang/test/Analysis/lambdas.cpp
index 0b6fc814e35b2..7a6d35e0d6b21 100644
--- a/clang/test/Analysis/lambdas.cpp
+++ b/clang/test/Analysis/lambdas.cpp
@@ -203,6 +203,22 @@ void testVariableLengthArrayCaptured() {
   clang_analyzer_eval(i == 7); // expected-warning{{TRUE}}
 }
 
+#if __cplusplus >= 201402L
+// Capture copy elided object.
+
+struct Elided{
+  int x = 0;
+  Elided(int) {}
+};
+
+void testCopyElidedObjectCaptured(int x) {
+  [e = Elided(x)] {
+    clang_analyzer_eval(e.x == 0); // expected-warning{{TRUE}}
+  }();
+}
+
+#endif
+
 // Test inline defensive checks
 int getNum();
 


        


More information about the cfe-commits mailing list