This revision was automatically updated to reflect the committed changes. Closed by commit rC360202: [analyzer] Fix a crash when doing RVO from within blocks. (authored by dergachev, committed by ).
Changed prior to commit: https://reviews.llvm.org/D61545?vs=198535&id=198555#toc Repository: rC Clang CHANGES SINCE LAST ACTION https://reviews.llvm.org/D61545/new/ https://reviews.llvm.org/D61545 Files: lib/StaticAnalyzer/Core/ExprEngineCXX.cpp test/Analysis/copy-elision.mm Index: lib/StaticAnalyzer/Core/ExprEngineCXX.cpp =================================================================== --- lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -196,6 +196,12 @@ // 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); Index: test/Analysis/copy-elision.mm =================================================================== --- test/Analysis/copy-elision.mm +++ 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
Index: lib/StaticAnalyzer/Core/ExprEngineCXX.cpp =================================================================== --- lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -196,6 +196,12 @@ // 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); Index: test/Analysis/copy-elision.mm =================================================================== --- test/Analysis/copy-elision.mm +++ 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
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits