diff options
author | Hans Wennborg <hans@hanshq.net> | 2015-01-10 01:19:48 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2015-01-10 01:19:48 +0000 |
commit | 43a0f99b103dc9c2546e650b99f5501e49e74dd2 (patch) | |
tree | 684a9d97c788f0d4ac39151128de445cd17530c4 /clang/test/CodeGenCXX | |
parent | 7c8a7251162d7e5db51e3ff7350a186fc749cee6 (diff) | |
download | bcm5719-llvm-43a0f99b103dc9c2546e650b99f5501e49e74dd2.tar.gz bcm5719-llvm-43a0f99b103dc9c2546e650b99f5501e49e74dd2.zip |
Don't emit implicit template instantiations eagerly (PR21718)
Their linkage can change if they are later explicitly instantiated. We would
previously emit such functions eagerly (as opposed to lazily on first use) if
they have a 'dllexport' or 'used' attribute, and fail an assert when hitting the
explicit instantiation.
This is achieved by replacing the old CodeGenModule::MayDeferGeneration() method
with two new ones: MustBeEmitted() and MayBeEmittedEagerly().
Differential Revision: http://reviews.llvm.org/D6674
llvm-svn: 225570
Diffstat (limited to 'clang/test/CodeGenCXX')
-rw-r--r-- | clang/test/CodeGenCXX/dllexport.cpp | 15 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/explicit-instantiation.cpp | 13 |
2 files changed, 28 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/dllexport.cpp b/clang/test/CodeGenCXX/dllexport.cpp index 5e2b3921c14..cfbc7e10078 100644 --- a/clang/test/CodeGenCXX/dllexport.cpp +++ b/clang/test/CodeGenCXX/dllexport.cpp @@ -615,6 +615,21 @@ NonExportedBaseClass::~NonExportedBaseClass() {} struct __declspec(dllexport) ExportedDerivedClass : NonExportedBaseClass {}; // M32-DAG: weak_odr dllexport x86_thiscallcc void @"\01??1ExportedDerivedClass@@UAE@XZ" +// Do not assert about generating code for constexpr functions twice during explicit instantiation (PR21718). +template <typename T> struct ExplicitInstConstexprMembers { + // Copy assignment operator + // M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable(1) %struct.ExplicitInstConstexprMembers* @"\01??4?$ExplicitInstConstexprMembers@X@@QAEAAU0@ABU0@@Z" + + constexpr ExplicitInstConstexprMembers() {} + // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExplicitInstConstexprMembers* @"\01??0?$ExplicitInstConstexprMembers@X@@QAE@XZ" + + ExplicitInstConstexprMembers(const ExplicitInstConstexprMembers&) = default; + // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExplicitInstConstexprMembers* @"\01??0?$ExplicitInstConstexprMembers@X@@QAE@ABU0@@Z" + + constexpr int f() const { return 42; } + // M32-DAG: define weak_odr dllexport x86_thiscallcc i32 @"\01?f@?$ExplicitInstConstexprMembers@X@@QBEHXZ" +}; +template struct __declspec(dllexport) ExplicitInstConstexprMembers<void>; //===----------------------------------------------------------------------===// // Classes with template base classes diff --git a/clang/test/CodeGenCXX/explicit-instantiation.cpp b/clang/test/CodeGenCXX/explicit-instantiation.cpp index 5bd06784cfa..6076444c25b 100644 --- a/clang/test/CodeGenCXX/explicit-instantiation.cpp +++ b/clang/test/CodeGenCXX/explicit-instantiation.cpp @@ -90,6 +90,19 @@ namespace LateInstantiation { // CHECK-OPT: define available_externally i32 @_ZN17LateInstantiation1fIiEEiv( } +namespace PR21718 { +// The linkage of a used constexpr member function can change from linkonce_odr +// to weak_odr after explicit instantiation without errors about defining the +// same function twice. +template <typename T> +struct S { +// CHECK-LABEL: define weak_odr i32 @_ZN7PR217181SIiE1fEv + __attribute__((used)) constexpr int f() { return 0; } +}; +int g() { return S<int>().f(); } +template struct S<int>; +} + // Check that we emit definitions from explicit instantiations even when they // occur prior to the definition itself. template <typename T> struct S { |