[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

llvm-svn: 360202
This commit is contained in:
Artem Dergachev 2019-05-07 22:33:13 +00:00
parent 2e977c083c
commit b3fc9df481
2 changed files with 24 additions and 0 deletions

View File

@ -196,6 +196,12 @@ std::pair<ProgramStateRef, SVal> ExprEngine::prepareForObjectConstruction(
// able to find construction context at all. // able to find construction context at all.
break; break;
} }
if (isa<BlockInvocationContext>(CallerLCtx)) {
// Unwrap block invocation contexts. They're mostly part of
// the current stack frame.
CallerLCtx = CallerLCtx->getParent();
assert(!isa<BlockInvocationContext>(CallerLCtx));
}
return prepareForObjectConstruction( return prepareForObjectConstruction(
cast<Expr>(SFC->getCallSite()), State, CallerLCtx, cast<Expr>(SFC->getCallSite()), State, CallerLCtx,
RTC->getConstructionContext(), CallOpts); RTC->getConstructionContext(), CallOpts);

View File

@ -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