diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -1147,23 +1147,12 @@ assert(InitExpr && "Capture missing initialization expression"); - if (const auto AILE = dyn_cast(InitExpr)) { - // If the AILE initializes a POD array, we need to keep it as the - // InitExpr. - if (dyn_cast(AILE->getSubExpr())) - InitExpr = AILE->getSubExpr(); - } - - // With C++17 copy elision this can happen. - if (const auto *FC = dyn_cast(InitExpr)) - InitExpr = FC->getSubExpr(); - - assert(InitExpr && - "Extracted capture initialization expression is missing"); - - if (dyn_cast(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 --- 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 @@ }(); } +static auto MakeUniquePtr() { return std::make_unique>(); } + +void testCopyElidedUniquePtr() { + [uniquePtr = MakeUniquePtr()] {}(); + clang_analyzer_warnIfReached(); // expected-warning{{TRUE}} +} + #endif // Test inline defensive checks