if (!RD || !RD->hasDefinition())
return RuntimeDefinition();
- // Find the decl for this method in that class.
- const CXXMethodDecl *Result = MD->getCorrespondingMethodInClass(RD, true);
+ const CXXMethodDecl *Result;
+ if (MD->getParent()->isDerivedFrom(RD)) {
+ // If our static type info is better than our dynamic type info, don't
+ // bother doing a search. Just use the static method.
+ Result = MD;
+ } else {
+ // Otherwise, find the decl for the method in the dynamic class.
+ Result = MD->getCorrespondingMethodInClass(RD, true);
+ }
+
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();
}
A a;
clang_analyzer_eval(a.get() == 0); // expected-warning{{TRUE}}
}
+
+
+namespace ReinterpretDisruptsDynamicTypeInfo {
+ class Parent {};
+
+ class Child : public Parent {
+ public:
+ virtual int foo() { return 42; }
+ };
+
+ void test(Parent *a) {
+ Child *b = reinterpret_cast<Child *>(a);
+ if (!b) return;
+ clang_analyzer_eval(b->foo() == 42); // expected-warning{{TRUE}} expected-warning{{UNKNOWN}}
+ }
+}