summaryrefslogtreecommitdiffstats
path: root/clang/test/CodeGenCXX/vtable-linkage.cpp
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/test/CodeGenCXX/vtable-linkage.cpp
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/test/CodeGenCXX/vtable-linkage.cpp')
-rw-r--r--clang/test/CodeGenCXX/vtable-linkage.cpp13
1 files changed, 5 insertions, 8 deletions
diff --git a/clang/test/CodeGenCXX/vtable-linkage.cpp b/clang/test/CodeGenCXX/vtable-linkage.cpp
index 48e6fc6a7cd..c17e33387e5 100644
--- a/clang/test/CodeGenCXX/vtable-linkage.cpp
+++ b/clang/test/CodeGenCXX/vtable-linkage.cpp
@@ -148,13 +148,13 @@ void use_F() {
// F<int> is an explicit template instantiation declaration without a
// key function, so its vtable should have external linkage.
// CHECK-DAG: @_ZTV1FIiE = external unnamed_addr constant
-// CHECK-OPT-DAG: @_ZTV1FIiE = available_externally unnamed_addr constant
+// CHECK-OPT-DAG: @_ZTV1FIiE = external unnamed_addr constant
// E<int> is an explicit template instantiation declaration. It has a
// key function that is not instantiated, so we should only reference
// its vtable, not define it.
// CHECK-DAG: @_ZTV1EIiE = external unnamed_addr constant
-// CHECK-OPT-DAG: @_ZTV1EIiE = available_externally unnamed_addr constant
+// CHECK-OPT-DAG: @_ZTV1EIiE = external unnamed_addr constant
// The anonymous struct for e has no linkage, so the vtable should have
// internal linkage.
@@ -202,17 +202,14 @@ void use_H() {
}
// I<int> has an explicit instantiation declaration and needs a VTT and
-// construction vtables. We emit the VTT available_externally, but point it at
-// internal construction vtables because there is no way to form a reference to
-// the real construction vtables.
+// construction vtables.
// CHECK-DAG: @_ZTV1IIiE = external unnamed_addr constant
// CHECK-DAG: @_ZTT1IIiE = external unnamed_addr constant
// CHECK-NOT: @_ZTC1IIiE
//
-// CHECK-OPT-DAG: @_ZTV1IIiE = available_externally unnamed_addr constant
-// CHECK-OPT-DAG: @_ZTT1IIiE = available_externally unnamed_addr constant {{.*}} @_ZTC1IIiE0_6VBase2
-// CHECK-OPT-DAG: @_ZTC1IIiE0_6VBase2 = internal unnamed_addr constant
+// CHECK-OPT-DAG: @_ZTV1IIiE = external unnamed_addr constant
+// CHECK-OPT-DAG: @_ZTT1IIiE = external unnamed_addr constant
struct VBase1 { virtual void f(); }; struct VBase2 : virtual VBase1 {};
template<typename T>
struct I : VBase2 {};
OpenPOWER on IntegriCloud