]> granicus.if.org Git - clang/commitdiff
[analyzer] Fix a crash when doing RVO from within blocks.
authorArtem Dergachev <artem.dergachev@gmail.com>
Tue, 7 May 2019 22:33:13 +0000 (22:33 +0000)
committerArtem Dergachev <artem.dergachev@gmail.com>
Tue, 7 May 2019 22:33:13 +0000 (22:33 +0000)
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

lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
test/Analysis/copy-elision.mm [new file with mode: 0644]

index aaab01f98c20f44dfb168eb213bc66b88501694c..62699fb3186b5a873b8ed86716d07d6f71190155 100644 (file)
@@ -196,6 +196,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);
diff --git a/test/Analysis/copy-elision.mm b/test/Analysis/copy-elision.mm
new file mode 100644 (file)
index 0000000..fa9435f
--- /dev/null
@@ -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