summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/DeclCXX.cpp
diff options
context:
space:
mode:
authorDavid Bolvansky <david.bolvansky@gmail.com>2019-08-31 18:52:44 +0000
committerDavid Bolvansky <david.bolvansky@gmail.com>2019-08-31 18:52:44 +0000
commit20b2708c18258efe01bc9b785e413362bcc1961c (patch)
tree15a0f17cdc6ca91774b3c2411a61dac1f3532e5b /clang/lib/AST/DeclCXX.cpp
parent8caa16ec13f2013fcbdb880b64782fa3bd39d97b (diff)
downloadbcm5719-llvm-20b2708c18258efe01bc9b785e413362bcc1961c.tar.gz
bcm5719-llvm-20b2708c18258efe01bc9b785e413362bcc1961c.zip
[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
Diffstat (limited to 'clang/lib/AST/DeclCXX.cpp')
-rw-r--r--clang/lib/AST/DeclCXX.cpp9
1 files changed, 7 insertions, 2 deletions
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 59710a55498..4939c37edc7 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -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()))
OpenPOWER on IntegriCloud