diff options
author | Hiroshi Yamauchi <yamauchi@google.com> | 2019-08-08 18:00:49 +0000 |
---|---|---|
committer | Hiroshi Yamauchi <yamauchi@google.com> | 2019-08-08 18:00:49 +0000 |
commit | cb30590da10ba80a133222588efedab7e5fc9bdd (patch) | |
tree | d5808f0c63bc5a7879b7e6a4715b2163129c7552 /clang/lib/CodeGen | |
parent | babdfdec90bb978799bcccf1ee0c856678b0ef7b (diff) | |
download | bcm5719-llvm-cb30590da10ba80a133222588efedab7e5fc9bdd.tar.gz bcm5719-llvm-cb30590da10ba80a133222588efedab7e5fc9bdd.zip |
Recommit Devirtualize destructor of final class.
Original patch commited as r364100, reverted as r364359, recommitted as r365509,
reverted as r365850.
llvm-svn: 368323
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGExprCXX.cpp | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index 5476d13b7c4..9057d160594 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -1882,9 +1882,33 @@ static void EmitObjectDelete(CodeGenFunction &CGF, Dtor = RD->getDestructor(); if (Dtor->isVirtual()) { - CGF.CGM.getCXXABI().emitVirtualObjectDelete(CGF, DE, Ptr, ElementType, - Dtor); - return; + bool UseVirtualCall = true; + const Expr *Base = DE->getArgument(); + 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; + } } } } |