Author: isuckatcs Date: 2022-08-22T13:00:31+02:00 New Revision: 3c482632e64c1a3e4967db325562f2e353513abc
URL: https://github.com/llvm/llvm-project/commit/3c482632e64c1a3e4967db325562f2e353513abc DIFF: https://github.com/llvm/llvm-project/commit/3c482632e64c1a3e4967db325562f2e353513abc.diff LOG: [analyzer] Remove pattern matching of lambda capture initializers Prior to this patch we handled lambda captures based on their initializer expression, which resulted in pattern matching. With C++17 copy elision the initializer expression can be anything, and this approach proved to be fragile and a source of crashes. This patch removes pattern matching and only checks whether the object is under construction or not. Differential Revision: https://reviews.llvm.org/D131944 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 d1b7ef7806ba7..c3f7719537789 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -1147,23 +1147,12 @@ void ExprEngine::VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred, 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 - // InitExpr. - if (dyn_cast<CXXConstructExpr>(AILE->getSubExpr())) - InitExpr = AILE->getSubExpr(); - } - - // 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); - InitVal = State->getSVal(InitVal.getAsRegion()); + // With C++17 copy elision the InitExpr can be anything, so instead of + // pattern matching all cases, we simple check if the current field is + // under construction or not, regardless what it's InitExpr is. + if (const auto OUC = + getObjectUnderConstruction(State, {LE, Idx}, LocCtxt)) { + InitVal = State->getSVal(OUC->getAsRegion()); State = finishObjectConstruction(State, {LE, Idx}, LocCtxt); } else diff --git a/clang/test/Analysis/lambdas.cpp b/clang/test/Analysis/lambdas.cpp index 7a6d35e0d6b21..b1d9784dcc0bf 100644 --- a/clang/test/Analysis/lambdas.cpp +++ b/clang/test/Analysis/lambdas.cpp @@ -3,6 +3,8 @@ // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,debug.DumpCFG -analyzer-config inline-lambdas=true %s > %t 2>&1 // RUN: FileCheck --input-file=%t %s +#include "Inputs/system-header-simulator-cxx.h" + void clang_analyzer_warnIfReached(); void clang_analyzer_eval(int); @@ -217,6 +219,13 @@ void testCopyElidedObjectCaptured(int x) { }(); } +static auto MakeUniquePtr() { return std::make_unique<std::vector<int>>(); } + +void testCopyElidedUniquePtr() { + [uniquePtr = MakeUniquePtr()] {}(); + clang_analyzer_warnIfReached(); // expected-warning{{TRUE}} +} + #endif // Test inline defensive checks _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits