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
diff --git a/clang/test/CodeGenCXX/thunks-available-externally.cpp b/clang/test/CodeGenCXX/thunks-available-externally.cpp
index 2997c36..01e4947 100644
--- a/clang/test/CodeGenCXX/thunks-available-externally.cpp
+++ b/clang/test/CodeGenCXX/thunks-available-externally.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -O3 -o - | FileCheck %s
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm-only -O3
// Check that we don't assert on this case.
namespace Test1 {
@@ -58,15 +58,6 @@
b->f();
}
-// CHECK-LABEL: define void @_ZN5Test21fEv()
-// CHECK: call void @_ZN5Test21C1fEv
-// CHECK: ret void
-// CHECK-LABEL: define available_externally void @_ZThn16_N5Test21C1fEv
-void f() {
- C c;
- f(&c);
-}
-
}
// Test that we don't assert.