This revision was automatically updated to reflect the committed changes. Closed by commit rGb4e3e3a3eb77: [analyzer] Fix a crash on copy elided initialized lambda captures (authored by isuckatcs). Herald added a project: clang. Herald added a subscriber: cfe-commits.
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D131784/new/ https://reviews.llvm.org/D131784 Files: clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp clang/test/Analysis/lambdas.cpp Index: clang/test/Analysis/lambdas.cpp =================================================================== --- clang/test/Analysis/lambdas.cpp +++ clang/test/Analysis/lambdas.cpp @@ -203,6 +203,22 @@ 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(); Index: clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -1143,7 +1143,9 @@ 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 @@ 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);
Index: clang/test/Analysis/lambdas.cpp =================================================================== --- clang/test/Analysis/lambdas.cpp +++ clang/test/Analysis/lambdas.cpp @@ -203,6 +203,22 @@ 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(); Index: clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -1143,7 +1143,9 @@ 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 @@ 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);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits