[cfe-commits] r163367 - in /cfe/trunk: lib/StaticAnalyzer/Core/CallEvent.cpp test/Analysis/inline.cpp

Jordan Rose jordan_rose at apple.com
Thu Sep 6 18:19:42 PDT 2012


Author: jrose
Date: Thu Sep  6 20:19:42 2012
New Revision: 163367

URL: http://llvm.org/viewvc/llvm-project?rev=163367&view=rev
Log:
[analyzer] Fail gracefully when the dynamic type is outside the hierarchy.

With some particularly evil casts, we can get an object whose dynamic type
is not actually a subclass of its static type. In this case, we won't even
find the statically-resolved method as a devirtualization candidate.

Rather than assert that this situation cannot occur, we now simply check
that the dynamic type is not an ancestor or descendent of the static type,
and leave it at that.

This error actually occurred analyzing LLVM: CallEventManager uses a
BumpPtrAllocator to allocate a concrete subclass of CallEvent
(FunctionCall), but then casts it to the actual subclass requested
(such as ObjCMethodCall) to perform the constructor.

Yet another crash in PR13763.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
    cfe/trunk/test/Analysis/inline.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp?rev=163367&r1=163366&r2=163367&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp Thu Sep  6 20:19:42 2012
@@ -435,7 +435,15 @@
 
   // Find the decl for this method in that class.
   const CXXMethodDecl *Result = MD->getCorrespondingMethodInClass(RD, true);
-  assert(Result && "At the very least the static decl should show up.");
+  if (!Result) {
+    // We might not even get the original statically-resolved method due to
+    // some particularly nasty casting (e.g. casts to sister classes).
+    // However, we should at least be able to search up and down our own class
+    // hierarchy, and some real bugs have been caught by checking this.
+    assert(!MD->getParent()->isDerivedFrom(RD) && "Bad DynamicTypeInfo");
+    assert(!RD->isDerivedFrom(MD->getParent()) && "Couldn't find known method");
+    return RuntimeDefinition();
+  }
 
   // Does the decl that we found have an implementation?
   const FunctionDecl *Definition;

Modified: cfe/trunk/test/Analysis/inline.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inline.cpp?rev=163367&r1=163366&r2=163367&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/inline.cpp (original)
+++ cfe/trunk/test/Analysis/inline.cpp Thu Sep  6 20:19:42 2012
@@ -267,3 +267,35 @@
     clang_analyzer_eval(obj->value == 42); // expected-warning{{UNKNOWN}}
   }
 }
+
+
+namespace VirtualWithSisterCasts {
+  struct Parent {
+    virtual int foo();
+  };
+
+  struct A : Parent {
+    virtual int foo() { return 42; }
+  };
+
+  struct B : Parent {
+    virtual int foo();
+  };
+
+  struct Unrelated {};
+
+  void testDowncast(Parent *b) {
+    A *a = (A *)(void *)b;
+    clang_analyzer_eval(a->foo() == 42); // expected-warning{{UNKNOWN}}
+  }
+
+  void testRelated(B *b) {
+    A *a = (A *)(void *)b;
+    clang_analyzer_eval(a->foo() == 42); // expected-warning{{UNKNOWN}}
+  }
+
+  void testUnrelated(Unrelated *b) {
+    A *a = (A *)(void *)b;
+    clang_analyzer_eval(a->foo() == 42); // expected-warning{{UNKNOWN}}
+  }
+}





More information about the cfe-commits mailing list