summaryrefslogtreecommitdiff
path: root/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2016-09-13 21:08:20 +0000
committerHans Wennborg <hans@hanshq.net>2016-09-13 21:08:20 +0000
commit3a10548d229142f4ba8ebc662e5fd4270ea680c8 (patch)
tree362a343b0a4a5513f90cc56016e5ee1629d4411e /lib/CodeGen/CodeGenModule.cpp
parentec0b188c06387c03d2c5c138efe1f47e8b678499 (diff)
downloadclang-3a10548d229142f4ba8ebc662e5fd4270ea680c8.tar.gz
Try harder to not inline dllimport functions referencing non-dllimport functions
In r246338, code was added to check for this, but it failed to take into account implicit destructor invocations because those are not reflected in the AST. This adds a separate check for them. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@281395 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CodeGenModule.cpp')
-rw-r--r--lib/CodeGen/CodeGenModule.cpp25
1 files changed, 23 insertions, 2 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 1b6f5c376d..085482b652 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -1740,8 +1740,17 @@ CodeGenModule::isTriviallyRecursive(const FunctionDecl *FD) {
return Walker.Result;
}
-bool
-CodeGenModule::shouldEmitFunction(GlobalDecl GD) {
+// Check if T is a class type with a destructor that's not dllimport.
+static bool HasNonDllImportDtor(QualType T) {
+ if (const RecordType *RT = dyn_cast<RecordType>(T))
+ if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
+ if (RD->getDestructor() && !RD->getDestructor()->hasAttr<DLLImportAttr>())
+ return true;
+
+ return false;
+}
+
+bool CodeGenModule::shouldEmitFunction(GlobalDecl GD) {
if (getFunctionLinkage(GD) != llvm::Function::AvailableExternallyLinkage)
return true;
const auto *F = cast<FunctionDecl>(GD.getDecl());
@@ -1754,6 +1763,18 @@ CodeGenModule::shouldEmitFunction(GlobalDecl GD) {
Visitor.TraverseFunctionDecl(const_cast<FunctionDecl*>(F));
if (!Visitor.SafeToInline)
return false;
+
+ if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(F)) {
+ // Implicit destructor invocations aren't captured in the AST, so the
+ // check above can't see them. Check for them manually here.
+ for (const Decl *Member : Dtor->getParent()->decls())
+ if (isa<FieldDecl>(Member))
+ if (HasNonDllImportDtor(cast<FieldDecl>(Member)->getType()))
+ return false;
+ for (const CXXBaseSpecifier &B : Dtor->getParent()->bases())
+ if (HasNonDllImportDtor(B.getType()))
+ return false;
+ }
}
// PR9614. Avoid cases where the source code is lying to us. An available