[analyzer] Try to devirtualize even if the static callee has no definition.

This mostly affects pure virtual methods, but would also affect parent
methods defined inline in the header when analyzing the child's source file.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161709 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/StaticAnalyzer/Core/CallEvent.cpp b/lib/StaticAnalyzer/Core/CallEvent.cpp
index 6635067..0f24bce 100644
--- a/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -383,13 +383,13 @@
 
 
 RuntimeDefinition CXXInstanceCall::getRuntimeDefinition() const {
-  const Decl *D = SimpleCall::getRuntimeDefinition().getDecl();
+  const Decl *D = getDecl();
   if (!D)
     return RuntimeDefinition();
 
   const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
   if (!MD->isVirtual())
-    return RuntimeDefinition(MD);
+    return SimpleCall::getRuntimeDefinition();
 
   // If the method is virtual, see if we can find the actual implementation
   // based on context-sensitivity.
diff --git a/test/Analysis/inline.cpp b/test/Analysis/inline.cpp
index d16eeaf..4298e1a 100644
--- a/test/Analysis/inline.cpp
+++ b/test/Analysis/inline.cpp
@@ -1,6 +1,7 @@
 // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -verify %s
 
 void clang_analyzer_eval(bool);
+void clang_analyzer_checkInlined(bool);
 
 class A {
 public:
@@ -43,3 +44,30 @@
   clang_analyzer_eval(ptr->getNum() == x); // expected-warning {{TRUE}}
 }
 
+
+namespace PureVirtualParent {
+  class Parent {
+  public:
+    virtual int pureVirtual() const = 0;
+    int callVirtual() const {
+      return pureVirtual();
+    }
+  };
+
+  class Child : public Parent {
+  public:
+    virtual int pureVirtual() const {
+      clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
+      return 42;
+    }
+  };
+
+  void testVirtual() {
+    Child x;
+
+    clang_analyzer_eval(x.pureVirtual() == 42); // expected-warning{{TRUE}}
+    clang_analyzer_eval(x.callVirtual() == 42); // expected-warning{{TRUE}}
+  }
+}
+
+