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