Skip to content

Commit

Permalink
[analyzer] Fix a crash when doing RVO from within blocks.
Browse files Browse the repository at this point in the history
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
(cherry picked from commit f587801)
  • Loading branch information
haoNoQ committed May 10, 2019
1 parent 399bd27 commit 7bd17df
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 0 deletions.
6 changes: 6 additions & 0 deletions lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,12 @@ std::pair<ProgramStateRef, SVal> ExprEngine::prepareForObjectConstruction(
// able to find construction context at all.
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(
cast<Expr>(SFC->getCallSite()), State, CallerLCtx,
RTC->getConstructionContext(), CallOpts);
Expand Down
18 changes: 18 additions & 0 deletions test/Analysis/copy-elision.mm
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 7bd17df

Please sign in to comment.