diff options
author | Reid Kleckner <reid@kleckner.net> | 2014-10-15 16:38:00 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2014-10-15 16:38:00 +0000 |
commit | 72d03bee6497a80e70ffbf43a6e28cd55bf3527b (patch) | |
tree | 09fea6116d7e6dda7d48a943cbcf219e4d508aee /clang/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp | |
parent | 8476abe288582a290f47a9808a32b82ea0dfb303 (diff) | |
download | llvm-72d03bee6497a80e70ffbf43a6e28cd55bf3527b.zip llvm-72d03bee6497a80e70ffbf43a6e28cd55bf3527b.tar.gz llvm-72d03bee6497a80e70ffbf43a6e28cd55bf3527b.tar.bz2 |
Don't use a global_ctors comdat for globals that aren't externally visible
In particular, if you have two identical templates in different TUs in
anonymous namespaces, we would use the same global_ctors comdat key for
both. As a result, only one would be run.
llvm-svn: 219806
Diffstat (limited to 'clang/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp')
-rw-r--r-- | clang/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/clang/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp b/clang/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp index 04bf79f..430fa2b 100644 --- a/clang/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp +++ b/clang/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp @@ -14,7 +14,7 @@ template<> int A<char>::a; // ALL: @_ZN1AIbE1aE = global i32 10 template<> int A<bool>::a = 10; -// ALL: @llvm.global_ctors = appending global [7 x { i32, void ()*, i8* }] +// ALL: @llvm.global_ctors = appending global [8 x { i32, void ()*, i8* }] // ELF: [{ i32, void ()*, i8* } { i32 65535, void ()* @[[unordered1:[^,]*]], i8* bitcast (i32* @_ZN1AIsE1aE to i8*) }, // MACHO: [{ i32, void ()*, i8* } { i32 65535, void ()* @[[unordered1:[^,]*]], i8* null }, @@ -34,6 +34,8 @@ template<> int A<bool>::a = 10; // ELF: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered6:[^,]*]], i8* @_Z1xIcE }, // MACHO: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered6:[^,]*]], i8* null }, +// ALL: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered7:[^,]*]], i8* null }, + // ALL: { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_static_member_variable_explicit_specialization.cpp, i8* null }] template int A<short>::a; // Unordered @@ -67,6 +69,13 @@ struct b { template<typename T> T b::i = foo(); template int b::i<int>; } + +namespace { +template<typename T> struct Internal { static int a; }; +template<typename T> int Internal<T>::a = foo(); +} +int *use_internal_a = &Internal<int>::a; + // ALL: define internal void @[[unordered1]] // ALL: call i32 @foo() // ALL: store {{.*}} @_ZN1AIsE1aE @@ -97,6 +106,11 @@ template int b::i<int>; // ALL: store {{.*}} @_Z1xIcE // ALL: ret +// ALL: define internal void @[[unordered7]] +// ALL: call i32 @foo() +// ALL: store {{.*}} @_ZN12_GLOBAL__N_18InternalIiE1aE +// ALL: ret + // ALL: define internal void @_GLOBAL__sub_I_static_member_variable_explicit_specialization.cpp() // We call unique stubs for every ordered dynamic initializer in the TU. // ALL: call |