Author: xbolva00 Date: Sat Aug 31 11:52:44 2019 New Revision: 370597 URL: http://llvm.org/viewvc/llvm-project?rev=370597&view=rev Log: [clang] Devirtualization for classes with destructors marked as 'final'
A class with a destructor marked final cannot be derived from, so it should afford the same devirtualization opportunities as marking the entire class final. Patch by logan-5 (Logan Smith) Reviewed by rsmith Differential Revision: https://reviews.llvm.org/D66621 Modified: cfe/trunk/lib/AST/DeclCXX.cpp cfe/trunk/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp Modified: cfe/trunk/lib/AST/DeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=370597&r1=370596&r2=370597&view=diff ============================================================================== --- cfe/trunk/lib/AST/DeclCXX.cpp (original) +++ cfe/trunk/lib/AST/DeclCXX.cpp Sat Aug 31 11:52:44 2019 @@ -2067,10 +2067,15 @@ CXXMethodDecl *CXXMethodDecl::getDevirtu if (DevirtualizedMethod->hasAttr<FinalAttr>()) return DevirtualizedMethod; - // Similarly, if the class itself is marked 'final' it can't be overridden - // and we can therefore devirtualize the member function call. + // Similarly, if the class itself or its destructor is marked 'final', + // the class can't be derived from and we can therefore devirtualize the + // member function call. if (BestDynamicDecl->hasAttr<FinalAttr>()) return DevirtualizedMethod; + if (const auto *dtor = BestDynamicDecl->getDestructor()) { + if (dtor->hasAttr<FinalAttr>()) + return DevirtualizedMethod; + } if (const auto *DRE = dyn_cast<DeclRefExpr>(Base)) { if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) Modified: cfe/trunk/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp?rev=370597&r1=370596&r2=370597&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp (original) +++ cfe/trunk/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp Sat Aug 31 11:52:44 2019 @@ -24,11 +24,24 @@ namespace Test2 { } } -namespace Test3 { +namespace Test2a { struct A { + virtual ~A() final {} virtual int f(); }; + // CHECK-LABEL: define i32 @_ZN6Test2a1fEPNS_1AE + int f(A *a) { + // CHECK: call i32 @_ZN6Test2a1A1fEv + return a->f(); + } +} + + +namespace Test3 { + struct A { + virtual int f(); }; + struct B final : A { }; // CHECK-LABEL: define i32 @_ZN5Test31fEPNS_1BE _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits