Index: clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -188,6 +188,8 @@ // top frame of the analysis. const StackFrameContext *SFC = LCtx->getStackFrame(); if (const LocationContext *CallerLCtx = SFC->getParent()) { + // Skip non-stack-frame contexts. + const StackFrameContext *CallerSFC = CallerLCtx->getStackFrame(); auto RTC = (*SFC->getCallSiteBlock())[SFC->getIndex()] .getAs(); if (!RTC) { @@ -197,7 +199,7 @@ break; } return prepareForObjectConstruction( - cast(SFC->getCallSite()), State, CallerLCtx, + cast(SFC->getCallSite()), State, CallerSFC, RTC->getConstructionContext(), CallOpts); } else { // We are on the top frame of the analysis. We do not know where is the Index: clang/test/Analysis/copy-elision.mm =================================================================== --- /dev/null +++ clang/test/Analysis/copy-elision.mm @@ -0,0 +1,19 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core -fblocks -verify %s + +// expected-no-diagnostics + +namespace block_rvo_crash { +struct A {}; +struct B {}; + +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