[PATCH] D43659: [analyzer] Don't crash when dynamic type of a concrete region is hard-set with placement new.
Phabricator via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 27 12:57:03 PST 2018
This revision was automatically updated to reflect the committed changes.
Closed by commit rL326245: [analyzer] Don't crash when dynamic type of a variable is set via placement new. (authored by dergachev, committed by ).
Herald added a subscriber: llvm-commits.
Changed prior to commit:
https://reviews.llvm.org/D43659?vs=135572&id=136137#toc
Repository:
rL LLVM
https://reviews.llvm.org/D43659
Files:
cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
cfe/trunk/test/Analysis/new-dynamic-types.cpp
Index: cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
===================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ cfe/trunk/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())
Index: cfe/trunk/test/Analysis/new-dynamic-types.cpp
===================================================================
--- cfe/trunk/test/Analysis/new-dynamic-types.cpp
+++ cfe/trunk/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
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D43659.136137.patch
Type: text/x-patch
Size: 1846 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180227/3b0287c4/attachment-0001.bin>
More information about the cfe-commits
mailing list