[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