[PATCH] D61545: [analyzer] Fix a crash in RVO from within blocks.

Artem Dergachev via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon May 6 14:50:53 PDT 2019


NoQ updated this revision to Diff 198342.
NoQ added a comment.

No, this is all wrong. We shouldn't unwrap to the parent stack frame here. We should end up exactly in the location context in which the call has happened. But we should still unwrap the block invocation context, as an exception, because it's just a weird location context that goes before the stack frame but still has its corresponding `AnalysisDeclContext` tied to the *callee* stack frame.

These block invocation contexts are used, like, once, to help modeling captures. I should probably try to get rid of them entirely.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61545/new/

https://reviews.llvm.org/D61545

Files:
  clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
  clang/test/Analysis/copy-elision.mm


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
Index: clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ clang/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);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D61545.198342.patch
Type: text/x-patch
Size: 1377 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190506/4f501e83/attachment.bin>


More information about the cfe-commits mailing list