]> granicus.if.org Git - clang/commitdiff
In VirtualCallChecker, handle indirect calls
authorSam McCall <sam.mccall@gmail.com>
Tue, 31 Jan 2017 05:23:20 +0000 (05:23 +0000)
committerSam McCall <sam.mccall@gmail.com>
Tue, 31 Jan 2017 05:23:20 +0000 (05:23 +0000)
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/trunk@293604 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
test/Analysis/virtualcall.cpp

index 15e8ea31c4c4432afab793a64c504c761137e289..b47762b915ce9d2560f875857bb5f18b870e16e3 100644 (file)
@@ -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());
index e42b898a0738ecc80d6a9e3bce5c02c07d3f1bdc..311f0a137c6f4ba4d3164a84a9325a524b3e031e 100644 (file)
@@ -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"