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

Jordan Rose jordan_rose at apple.com
Thu Aug 21 08:56:04 PDT 2014


Thanks!

On Aug 21, 2014, at 3:25 , Benjamin Kramer <benny.kra at googlemail.com> wrote:

> 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"
> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits




More information about the cfe-commits mailing list