mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-20 03:55:48 -04:00
Recommit Devirtualize destructor of final class.
Original patch commited as r364100, reverted as r364359, recommitted as r365509, reverted as r365850. llvm-svn: 368323
This commit is contained in:
parent
babdfdec90
commit
cb30590da1
@ -1882,9 +1882,33 @@ static void EmitObjectDelete(CodeGenFunction &CGF,
|
|||||||
Dtor = RD->getDestructor();
|
Dtor = RD->getDestructor();
|
||||||
|
|
||||||
if (Dtor->isVirtual()) {
|
if (Dtor->isVirtual()) {
|
||||||
CGF.CGM.getCXXABI().emitVirtualObjectDelete(CGF, DE, Ptr, ElementType,
|
bool UseVirtualCall = true;
|
||||||
Dtor);
|
const Expr *Base = DE->getArgument();
|
||||||
return;
|
if (auto *DevirtualizedDtor =
|
||||||
|
dyn_cast_or_null<const CXXDestructorDecl>(
|
||||||
|
Dtor->getDevirtualizedMethod(
|
||||||
|
Base, CGF.CGM.getLangOpts().AppleKext))) {
|
||||||
|
UseVirtualCall = false;
|
||||||
|
const CXXRecordDecl *DevirtualizedClass =
|
||||||
|
DevirtualizedDtor->getParent();
|
||||||
|
if (declaresSameEntity(getCXXRecord(Base), DevirtualizedClass)) {
|
||||||
|
// Devirtualized to the class of the base type (the type of the
|
||||||
|
// whole expression).
|
||||||
|
Dtor = DevirtualizedDtor;
|
||||||
|
} else {
|
||||||
|
// Devirtualized to some other type. Would need to cast the this
|
||||||
|
// pointer to that type but we don't have support for that yet, so
|
||||||
|
// do a virtual call. FIXME: handle the case where it is
|
||||||
|
// devirtualized to the derived type (the type of the inner
|
||||||
|
// expression) as in EmitCXXMemberOrOperatorMemberCallExpr.
|
||||||
|
UseVirtualCall = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (UseVirtualCall) {
|
||||||
|
CGF.CGM.getCXXABI().emitVirtualObjectDelete(CGF, DE, Ptr, ElementType,
|
||||||
|
Dtor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
23
clang/test/CodeGenCXX/devirtualize-dtor-final.cpp
Normal file
23
clang/test/CodeGenCXX/devirtualize-dtor-final.cpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 %s -emit-llvm -o - | FileCheck %s
|
||||||
|
|
||||||
|
namespace Test1 {
|
||||||
|
struct A { virtual ~A() {} };
|
||||||
|
struct B final : A {};
|
||||||
|
struct C : A { virtual ~C() final {} };
|
||||||
|
struct D { virtual ~D() final = 0; };
|
||||||
|
// CHECK-LABEL: define void @_ZN5Test13fooEPNS_1BE
|
||||||
|
void foo(B *b) {
|
||||||
|
// CHECK: call void @_ZN5Test11BD1Ev
|
||||||
|
delete b;
|
||||||
|
}
|
||||||
|
// CHECK-LABEL: define void @_ZN5Test14foo2EPNS_1CE
|
||||||
|
void foo2(C *c) {
|
||||||
|
// CHECK: call void @_ZN5Test11CD1Ev
|
||||||
|
delete c;
|
||||||
|
}
|
||||||
|
// CHECK-LABEL: define void @_ZN5Test14evilEPNS_1DE
|
||||||
|
void evil(D *p) {
|
||||||
|
// CHECK-NOT: call void @_ZN5Test11DD1Ev
|
||||||
|
delete p;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user