From ee6aa0c62e8b9bc7fc63efe0abf78f0918d12808 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 3 Sep 2013 21:05:13 +0000 Subject: Don't emit an available_externally vtable pointing to linkonce_odr funcs. This fixes pr13124. From the discussion at http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-June/022606.html we know that we cannot make funcions in a weak_odr vtable also weak_odr. They should remain linkonce_odr. The side effect is that we cannot emit a available_externally vtable unless we also emit a copy of the function. This also has an issue: If codegen is going to output a function, sema has to mark it used. Given llvm.org/pr9114, it looks like sema cannot be more aggressive at marking functions used because of vtables. This leaves us with a few unpleasant options: * Marking functions in vtables used if possible. This sounds a bit sloppy, so we should avoid it. * Producing available_externally vtables only when all the functions in it are already used or weak_odr. This would cover cases like -------------------- struct foo { virtual ~foo(); }; struct bar : public foo { virtual void zed(); }; void f() { foo *x(new bar); delete x; } void g(bar *x) { x->~bar(); // force the destructor to be used } -------------------------- and ---------------------------------- template struct bar { virtual ~bar(); }; template bar::~bar() { } // make the destructor weak_odr instead of linkonce_odr extern template class bar; void f() { bar *x(new bar); delete x; } ---------------------------- These look like corner cases, so it is unclear if it is worth it. * And finally: Just nuke this optimization. That is what this patch implements. llvm-svn: 189852 --- clang/lib/CodeGen/CGVTables.cpp | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) (limited to 'clang/lib/CodeGen') diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index 26ebf913a9b..3585c42dc9f 100644 --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -753,12 +753,7 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) { switch (keyFunction->getTemplateSpecializationKind()) { case TSK_Undeclared: case TSK_ExplicitSpecialization: - // When compiling with optimizations turned on, we emit all vtables, - // even if the key function is not defined in the current translation - // unit. If this is the case, use available_externally linkage. - if (!def && CodeGenOpts.OptimizationLevel) - return llvm::GlobalVariable::AvailableExternallyLinkage; - + assert(def && "Should not have been asked to emit this"); if (keyFunction->isInlined()) return !Context.getLangOpts().AppleKext ? llvm::GlobalVariable::LinkOnceODRLinkage : @@ -777,9 +772,7 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) { llvm::Function::InternalLinkage; case TSK_ExplicitInstantiationDeclaration: - return !Context.getLangOpts().AppleKext ? - llvm::GlobalVariable::AvailableExternallyLinkage : - llvm::Function::InternalLinkage; + llvm_unreachable("Should not have been asked to emit this"); } } @@ -795,7 +788,7 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) { return llvm::GlobalVariable::LinkOnceODRLinkage; case TSK_ExplicitInstantiationDeclaration: - return llvm::GlobalVariable::AvailableExternallyLinkage; + llvm_unreachable("Should not have been asked to emit this"); case TSK_ExplicitInstantiationDefinition: return llvm::GlobalVariable::WeakODRLinkage; @@ -897,16 +890,6 @@ bool CodeGenVTables::isVTableExternal(const CXXRecordDecl *RD) { /// we define that v-table? static bool shouldEmitVTableAtEndOfTranslationUnit(CodeGenModule &CGM, const CXXRecordDecl *RD) { - // If we're building with optimization, we always emit v-tables - // since that allows for virtual function calls to be devirtualized. - // If the v-table is defined strongly elsewhere, this definition - // will be emitted available_externally. - // - // However, we don't want to do this in -fapple-kext mode, because - // kext mode does not permit devirtualization. - if (CGM.getCodeGenOpts().OptimizationLevel && !CGM.getLangOpts().AppleKext) - return true; - return !CGM.getVTables().isVTableExternal(RD); } -- cgit v1.2.3