summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2017-02-24 18:49:54 +0000
committerHans Wennborg <hans@hanshq.net>2017-02-24 18:49:54 +0000
commit7d2f60d33dcc26e06ffbac2d95c7c3bab044fadf (patch)
tree6ec24b436e2ec5e3bf8e17c40330a6c7aa277b9a
parent7aee01dd23677ba1024d6c089fb4af7c4d70fea0 (diff)
Merging r293604:
------------------------------------------------------------------------ r293604 | sammccall | 2017-01-30 21:23:20 -0800 (Mon, 30 Jan 2017) | 12 lines In VirtualCallChecker, handle indirect calls Summary: In VirtualCallChecker, handle indirect calls. getDirectCallee() can be nullptr, and dyn_cast(nullptr) is UB Reviewers: bkramer Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D29303 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_40@296154 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp3
-rw-r--r--test/Analysis/virtualcall.cpp11
2 files changed, 13 insertions, 1 deletions
diff --git a/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp b/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
index 15e8ea31c4..b47762b915 100644
--- a/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
@@ -179,7 +179,8 @@ void WalkAST::VisitCXXMemberCallExpr(CallExpr *CE) {
}
// Get the callee.
- const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CE->getDirectCallee());
+ const CXXMethodDecl *MD =
+ dyn_cast_or_null<CXXMethodDecl>(CE->getDirectCallee());
if (MD && MD->isVirtual() && !callIsNonVirtual && !MD->hasAttr<FinalAttr>() &&
!MD->getParent()->hasAttr<FinalAttr>())
ReportVirtualCall(CE, MD->isPure());
diff --git a/test/Analysis/virtualcall.cpp b/test/Analysis/virtualcall.cpp
index e42b898a07..311f0a137c 100644
--- a/test/Analysis/virtualcall.cpp
+++ b/test/Analysis/virtualcall.cpp
@@ -115,12 +115,23 @@ public:
int foo() override;
};
+// Regression test: don't crash when there's no direct callee.
+class F {
+public:
+ F() {
+ void (F::* ptr)() = &F::foo;
+ (this->*ptr)();
+ }
+ void foo();
+};
+
int main() {
A *a;
B *b;
C *c;
D *d;
E *e;
+ F *f;
}
#include "virtualcall.h"