[PATCH] D43659: [analyzer] Don't crash when dynamic type of a concrete region is hard-set with placement new.

Artem Dergachev via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 22 17:22:45 PST 2018


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

- Add a definitely-not-UB example (`char` buffers are special).
- Bring back an accidentally deleted blank line.


https://reviews.llvm.org/D43659

Files:
  lib/StaticAnalyzer/Core/CallEvent.cpp
  test/Analysis/new-dynamic-types.cpp


Index: test/Analysis/new-dynamic-types.cpp
===================================================================
--- /dev/null
+++ test/Analysis/new-dynamic-types.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -std=c++11 -verify %s
+
+// expected-no-diagnostics
+
+typedef __typeof(sizeof(int)) size_t;
+
+void *operator new(size_t size, void *ptr);
+
+struct B {
+  virtual void foo();
+};
+
+struct D : public B {
+  virtual void foo() override {}
+};
+
+void test_ub() {
+  // FIXME: Potentially warn because this code is pretty weird.
+  B b;
+  new (&b) D;
+  b.foo(); // no-crash
+}
+
+void test_non_ub() {
+  char c[sizeof(D)]; // Should be enough storage.
+  new (c) D;
+  ((B *)c)->foo(); // no-crash
+}
Index: lib/StaticAnalyzer/Core/CallEvent.cpp
===================================================================
--- lib/StaticAnalyzer/Core/CallEvent.cpp
+++ lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -587,7 +587,15 @@
       // FIXME: CallEvent maybe shouldn't be directly accessing StoreManager.
       bool Failed;
       ThisVal = StateMgr.getStoreManager().attemptDownCast(ThisVal, Ty, Failed);
-      assert(!Failed && "Calling an incorrectly devirtualized method");
+      if (Failed) {
+        // We might have suffered some sort of placement new earlier, so
+        // we're constructing in a completely unexpected storage.
+        // Fall back to a generic pointer cast for this-value.
+        const CXXMethodDecl *StaticMD = cast<CXXMethodDecl>(getDecl());
+        const CXXRecordDecl *StaticClass = StaticMD->getParent();
+        QualType StaticTy = Ctx.getPointerType(Ctx.getRecordType(StaticClass));
+        ThisVal = SVB.evalCast(ThisVal, Ty, StaticTy);
+      }
     }
 
     if (!ThisVal.isUnknown())


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D43659.135572.patch
Type: text/x-patch
Size: 1760 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180223/256b84d8/attachment.bin>


More information about the cfe-commits mailing list