r216167 - [analyzer] Don't warn on virtual calls in ctors to final methods.

Benjamin Kramer benny.kra at googlemail.com
Thu Aug 21 03:25:04 PDT 2014


Author: d0k
Date: Thu Aug 21 05:25:03 2014
New Revision: 216167

URL: http://llvm.org/viewvc/llvm-project?rev=216167&view=rev
Log:
[analyzer] Don't warn on virtual calls in ctors to final methods.

The call will never go to a more derived class, but that's intentional in those
cases.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
    cfe/trunk/test/Analysis/virtualcall.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp?rev=216167&r1=216166&r2=216167&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp Thu Aug 21 05:25:03 2014
@@ -146,15 +146,22 @@ void WalkAST::VisitCXXMemberCallExpr(Cal
     if (CME->getQualifier())
       callIsNonVirtual = true;
 
-    // Elide analyzing the call entirely if the base pointer is not 'this'.
-    if (Expr *base = CME->getBase()->IgnoreImpCasts())
+    if (Expr *base = CME->getBase()->IgnoreImpCasts()) {
+      // Elide analyzing the call entirely if the base pointer is not 'this'.
       if (!isa<CXXThisExpr>(base))
         return;
+
+      // If the most derived class is marked final, we know that now subclass
+      // can override this member.
+      if (base->getBestDynamicClassType()->hasAttr<FinalAttr>())
+        callIsNonVirtual = true;
+    }
   }
 
   // Get the callee.
   const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CE->getDirectCallee());
-  if (MD && MD->isVirtual() && !callIsNonVirtual)
+  if (MD && MD->isVirtual() && !callIsNonVirtual && !MD->hasAttr<FinalAttr>() &&
+      !MD->getParent()->hasAttr<FinalAttr>())
     ReportVirtualCall(CE, MD->isPure());
 
   Enqueue(CE);

Modified: cfe/trunk/test/Analysis/virtualcall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/virtualcall.cpp?rev=216167&r1=216166&r2=216167&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/virtualcall.cpp (original)
+++ cfe/trunk/test/Analysis/virtualcall.cpp Thu Aug 21 05:25:03 2014
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.cplusplus.VirtualCall -analyzer-store region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.cplusplus.VirtualCall -analyzer-store region -verify -std=c++11 %s
 
 class A {
 public:
@@ -46,10 +46,31 @@ C::C() {
   f(foo()); // expected-warning{{Call virtual functions during construction or destruction will never go to a more derived class}}
 }
 
+class D : public B {
+public:
+  D() {
+    foo(); // no-warning
+  }
+  ~D() { bar(); }
+  int foo() final;
+  void bar() final { foo(); } // no-warning
+};
+
+class E final : public B {
+public:
+  E() {
+    foo(); // no-warning
+  }
+  ~E() { bar(); }
+  int foo() override;
+};
+
 int main() {
   A *a;
   B *b;
   C *c;
+  D *d;
+  E *e;
 }
 
 #include "virtualcall.h"





More information about the cfe-commits mailing list