From 93f7547260f1e490fd95b68f05f0b69d356ce8be Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 13 Sep 2016 21:08:20 +0000 Subject: 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. llvm-svn: 281395 --- clang/lib/CodeGen/CodeGenModule.cpp | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'clang/lib/CodeGen/CodeGenModule.cpp') diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 1b6f5c3..085482b 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/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(T)) + if (CXXRecordDecl *RD = dyn_cast(RT->getDecl())) + if (RD->getDestructor() && !RD->getDestructor()->hasAttr()) + return true; + + return false; +} + +bool CodeGenModule::shouldEmitFunction(GlobalDecl GD) { if (getFunctionLinkage(GD) != llvm::Function::AvailableExternallyLinkage) return true; const auto *F = cast(GD.getDecl()); @@ -1754,6 +1763,18 @@ CodeGenModule::shouldEmitFunction(GlobalDecl GD) { Visitor.TraverseFunctionDecl(const_cast(F)); if (!Visitor.SafeToInline) return false; + + if (const CXXDestructorDecl *Dtor = dyn_cast(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(Member)) + if (HasNonDllImportDtor(cast(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 -- cgit v1.1