summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/StaticAnalyzer/Core/CallEvent.cpp10
-rw-r--r--clang/test/Analysis/inline.cpp32
2 files changed, 41 insertions, 1 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
index 7d58e806a73..50d16f97283 100644
--- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -435,7 +435,15 @@ RuntimeDefinition CXXInstanceCall::getRuntimeDefinition() const {
// 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;
diff --git a/clang/test/Analysis/inline.cpp b/clang/test/Analysis/inline.cpp
index 573b1647a33..6491b12c585 100644
--- a/clang/test/Analysis/inline.cpp
+++ b/clang/test/Analysis/inline.cpp
@@ -267,3 +267,35 @@ namespace OperatorNew {
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}}
+ }
+}
OpenPOWER on IntegriCloud