From: Artem Dergachev Date: Tue, 7 May 2019 22:33:13 +0000 (+0000) Subject: [analyzer] Fix a crash when doing RVO from within blocks. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f587801ce99f6c812fd961e4147327c3f8e8bef4;p=clang [analyzer] Fix a crash when doing RVO from within blocks. When looking for the location context of the call site, unwrap block invocation contexts because they are attached to the current AnalysisDeclContext while what we need is the previous AnalysisDeclContext. Differential Revision: https://reviews.llvm.org/D61545 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@360202 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp index aaab01f98c..62699fb318 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -196,6 +196,12 @@ std::pair ExprEngine::prepareForObjectConstruction( // able to find construction context at all. break; } + if (isa(CallerLCtx)) { + // Unwrap block invocation contexts. They're mostly part of + // the current stack frame. + CallerLCtx = CallerLCtx->getParent(); + assert(!isa(CallerLCtx)); + } return prepareForObjectConstruction( cast(SFC->getCallSite()), State, CallerLCtx, RTC->getConstructionContext(), CallOpts); diff --git a/test/Analysis/copy-elision.mm b/test/Analysis/copy-elision.mm new file mode 100644 index 0000000000..fa9435f599 --- /dev/null +++ b/test/Analysis/copy-elision.mm @@ -0,0 +1,18 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core -fblocks -verify %s + +// expected-no-diagnostics + +namespace block_rvo_crash { +struct A {}; + +A getA(); +void use(A a) {} + +void foo() { + // This used to crash when finding construction context for getA() + // (which is use()'s argument due to RVO). + use(^{ + return getA(); // no-crash + }()); +} +} // namespace block_rvo_crash