summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2013-09-03 21:05:13 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2013-09-03 21:05:13 +0000
commitee6aa0c62e8b9bc7fc63efe0abf78f0918d12808 (patch)
treede2a483004e571695b18c2f8605fe553c7398cd4 /clang/lib
parentf58070baed3a05c90e5d5fb969c612472eea4e3d (diff)
downloadbcm5719-llvm-ee6aa0c62e8b9bc7fc63efe0abf78f0918d12808.tar.gz
bcm5719-llvm-ee6aa0c62e8b9bc7fc63efe0abf78f0918d12808.zip
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<typename T> struct bar { virtual ~bar(); }; template<typename T> bar<T>::~bar() { } // make the destructor weak_odr instead of linkonce_odr extern template class bar<int>; void f() { bar<int> *x(new bar<int>); 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
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CGVTables.cpp23
1 files changed, 3 insertions, 20 deletions
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);
}
OpenPOWER on IntegriCloud