summaryrefslogtreecommitdiffstats
path: root/test/CodeGenCXX/ctor-dtor-alias.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2014-09-16 15:18:21 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2014-09-16 15:18:21 +0000
commitf0bac949ec3a49796b79ef3ac1bafaeda0b2c057 (patch)
treecade16073f9cc300688e148781453080cc84ca58 /test/CodeGenCXX/ctor-dtor-alias.cpp
parent5ce1cbcffd7625935379d405d76af576bfec0d8d (diff)
Add support for putting constructors and destructos in explicit comdats.
There are situations when clang knows that the C1 and C2 constructors or the D1 and D2 destructors are identical. We already optimize some of these cases, but cannot optimize it when the GlobalValue is weak_odr. The problem with weak_odr is that an old TU seeing the same code will have a C1 and a C2 comdat with the corresponding symbols. We cannot suddenly start putting the C2 symbol in the C1 comdat as we cannot guarantee that the linker will not pick a .o with only C1 in it. The solution implemented by GCC is to expand the ABI to have a comdat whose name uses a C5/D5 suffix and always has both symbols. That is what this patch implements. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@217874 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/ctor-dtor-alias.cpp')
-rw-r--r--test/CodeGenCXX/ctor-dtor-alias.cpp58
1 files changed, 49 insertions, 9 deletions
diff --git a/test/CodeGenCXX/ctor-dtor-alias.cpp b/test/CodeGenCXX/ctor-dtor-alias.cpp
index 8be5494df2..10923d1bc7 100644
--- a/test/CodeGenCXX/ctor-dtor-alias.cpp
+++ b/test/CodeGenCXX/ctor-dtor-alias.cpp
@@ -6,18 +6,23 @@
// RUN: FileCheck --check-prefix=CHECK3 --input-file=%t %s
// RUN: FileCheck --check-prefix=CHECK4 --input-file=%t %s
// RUN: FileCheck --check-prefix=CHECK5 --input-file=%t %s
+// RUN: FileCheck --check-prefix=CHECK6 --input-file=%t %s
namespace test1 {
-// test that we don't produce an alias when the destructor is weak_odr. The
-// reason to avoid it that another TU might have no explicit template
-// instantiation definition or declaration, causing it to to output only
-// one of the destructors as linkonce_odr, producing a different comdat.
-
-// CHECK1: define weak_odr void @_ZN5test16foobarIvEC2Ev
-// CHECK1: define weak_odr void @_ZN5test16foobarIvEC1Ev
-
-template <typename T> struct foobar {
+// Test that we produce the apropriate comdats when creating aliases to
+// weak_odr constructors and destructors.
+
+// CHECK1: @_ZN5test16foobarIvEC1Ev = weak_odr alias void {{.*}} @_ZN5test16foobarIvEC2Ev
+// CHECK1: @_ZN5test16foobarIvED1Ev = weak_odr alias void (%"struct.test1::foobar"*)* @_ZN5test16foobarIvED2Ev
+// CHECK1: define weak_odr void @_ZN5test16foobarIvEC2Ev({{.*}} comdat $_ZN5test16foobarIvEC5Ev
+// CHECK1: define weak_odr void @_ZN5test16foobarIvED2Ev({{.*}} comdat $_ZN5test16foobarIvED5Ev
+// CHECK1: define weak_odr void @_ZN5test16foobarIvED0Ev({{.*}} comdat $_ZN5test16foobarIvED5Ev
+// CHECK1-NOT: comdat
+
+template <typename T>
+struct foobar {
foobar() {}
+ virtual ~foobar() {}
};
template struct foobar<void>;
@@ -187,3 +192,38 @@ void
fn1() {
new C;
}
+
+namespace test10 {
+// Test that if a destructor is in a comdat, we don't try to emit is as an
+// alias to a base class destructor.
+struct bar {
+ ~bar();
+};
+bar::~bar() {
+}
+} // closing the namespace causes ~bar to be sent to CodeGen
+namespace test10 {
+template <typename T>
+struct foo : public bar {
+ ~foo();
+};
+template <typename T>
+foo<T>::~foo() {}
+template class foo<int>;
+// CHECK5: define weak_odr void @_ZN6test103fooIiED2Ev({{.*}} comdat $_ZN6test103fooIiED5Ev
+}
+
+namespace test11 {
+// Test that when we don't have to worry about COMDATs we produce an alias
+// from complate to base and from base to base class base.
+struct bar {
+ ~bar();
+};
+bar::~bar() {}
+struct foo : public bar {
+ ~foo();
+};
+foo::~foo() {}
+// CHECK6: @_ZN6test113fooD2Ev = alias {{.*}} @_ZN6test113barD2Ev
+// CHECK6: @_ZN6test113fooD1Ev = alias {{.*}} @_ZN6test113fooD2Ev
+}