summaryrefslogtreecommitdiffstats
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
commit51bcb226a2745d6a7416b30bc2cf54ed4b6c2209 (patch)
treee5de788f1e83bc6630ab608d19c6ba98c4c7eacd
parent13937b1d7a730111b61355b74674a42f8901c2f5 (diff)
downloadbcm5719-llvm-51bcb226a2745d6a7416b30bc2cf54ed4b6c2209.tar.gz
bcm5719-llvm-51bcb226a2745d6a7416b30bc2cf54ed4b6c2209.zip
[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. llvm-svn: 161709
-rw-r--r--clang/lib/StaticAnalyzer/Core/CallEvent.cpp4
-rw-r--r--clang/test/Analysis/inline.cpp28
2 files changed, 30 insertions, 2 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
index 6635067d0f9..0f24bce70b5 100644
--- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/clang/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/clang/test/Analysis/inline.cpp b/clang/test/Analysis/inline.cpp
index d16eeaf619b..4298e1aac82 100644
--- a/clang/test/Analysis/inline.cpp
+++ b/clang/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}}
+ }
+}
+
+
OpenPOWER on IntegriCloud