forked from OSchip/llvm-project
[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 llvm-svn: 370597
This commit is contained in:
parent
8caa16ec13
commit
20b2708c18
|
@ -2067,10 +2067,15 @@ CXXMethodDecl *CXXMethodDecl::getDevirtualizedMethod(const Expr *Base,
|
|||
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()))
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue