aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-08-10 22:26:43 +0000
committerJordan Rose <jordan_rose@apple.com>2012-08-10 22:26:43 +0000
commit9584f67b6da17283a31dedf0a1cab2d83a3d121c (patch)
treea8b5738c2e422d942b1921bb4f4461f6b4485fca
parente5399f1375f8571bdd821ae08291af1c895adfd3 (diff)
[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
-rw-r--r--lib/StaticAnalyzer/Core/CallEvent.cpp4
-rw-r--r--test/Analysis/inline.cpp28
2 files changed, 30 insertions, 2 deletions
diff --git a/lib/StaticAnalyzer/Core/CallEvent.cpp b/lib/StaticAnalyzer/Core/CallEvent.cpp
index 6635067d0f..0f24bce70b 100644
--- a/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -383,13 +383,13 @@ static const CXXMethodDecl *devirtualize(const CXXMethodDecl *MD, SVal ThisVal){
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 d16eeaf619..4298e1aac8 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 @@ void testPathSensitivity(int x) {
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}}
+ }
+}
+
+