diff options
author | Hans Wennborg <hans@hanshq.net> | 2015-08-28 21:47:01 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2015-08-28 21:47:01 +0000 |
commit | 2c55320819060df8462d9a6e0e28d3f8e53574a6 (patch) | |
tree | 76d5c1669fe89f6d7713a390332a6811d6c8f743 /test/CodeGenCXX/dllimport.cpp | |
parent | 6223b3f9891eaf4da7a0b616f9c869b2639bdd6d (diff) |
Allow TLS vars in dllimport/export functions; only inline dllimport functions when safe (PR24593)
This patch does two things:
1) Don't error about dllimport/export on thread-local static local variables.
We put those attributes on static locals in dllimport/export functions
implicitly in case the function gets inlined. Now, for TLS variables this
is a problem because we can't import such variables, but it's a benign
problem becase:
2) Make sure we never inline a dllimport function TLS static locals. In fact,
never inline a dllimport function that references a non-imported function
or variable (because these are not defined in the importing library). This
seems to match MSVC's behaviour.
Differential Revision: http://reviews.llvm.org/D12422
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@246338 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/dllimport.cpp')
-rw-r--r-- | test/CodeGenCXX/dllimport.cpp | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/test/CodeGenCXX/dllimport.cpp b/test/CodeGenCXX/dllimport.cpp index c87d959c5b..b9c850b8b8 100644 --- a/test/CodeGenCXX/dllimport.cpp +++ b/test/CodeGenCXX/dllimport.cpp @@ -86,7 +86,7 @@ USEVAR(GlobalRedecl3) namespace ns { __declspec(dllimport) int ExternalGlobal; } USEVAR(ns::ExternalGlobal) -int f(); +int __declspec(dllimport) f(); // MO1-DAG: @"\01?x@?1??inlineStaticLocalsFunc@@YAHXZ@4HA" = available_externally dllimport global i32 0 // MO1-DAG: @"\01??_B?1??inlineStaticLocalsFunc@@YAHXZ@51" = available_externally dllimport global i32 0 inline int __declspec(dllimport) inlineStaticLocalsFunc() { @@ -314,6 +314,46 @@ void UNIQ(use)() { ::operator new(42); } namespace ns { __declspec(dllimport) void externalFunc(); } USE(ns::externalFunc) +// A dllimport function referencing non-imported vars or functions must not be available_externally. +__declspec(dllimport) int ImportedVar; +int NonImportedVar; +__declspec(dllimport) int ImportedFunc(); +int NonImportedFunc(); +__declspec(dllimport) inline int ReferencingImportedVar() { return ImportedVar; } +// MO1-DAG: define available_externally dllimport i32 @"\01?ReferencingImportedVar@@YAHXZ" +__declspec(dllimport) inline int ReferencingNonImportedVar() { return NonImportedVar; } +// MO1-DAG: declare dllimport i32 @"\01?ReferencingNonImportedVar@@YAHXZ"() +__declspec(dllimport) inline int ReferencingImportedFunc() { return ImportedFunc(); } +// MO1-DAG: define available_externally dllimport i32 @"\01?ReferencingImportedFunc@@YAHXZ" +__declspec(dllimport) inline int ReferencingNonImportedFunc() { return NonImportedFunc(); } +// MO1-DAG: declare dllimport i32 @"\01?ReferencingNonImportedFunc@@YAHXZ"() +USE(ReferencingImportedVar) +USE(ReferencingNonImportedVar) +USE(ReferencingImportedFunc) +USE(ReferencingNonImportedFunc) +// References to operator new and delete count too, despite not being DeclRefExprs. +__declspec(dllimport) inline int *ReferencingNonImportedNew() { return new int[2]; } +// MO1-DAG: declare dllimport i32* @"\01?ReferencingNonImportedNew@@YAPAHXZ" +__declspec(dllimport) inline int *ReferencingNonImportedDelete() { delete (int*)nullptr; } +// MO1-DAG: declare dllimport i32* @"\01?ReferencingNonImportedDelete@@YAPAHXZ" +USE(ReferencingNonImportedNew) +USE(ReferencingNonImportedDelete) +__declspec(dllimport) void* operator new[](__SIZE_TYPE__); +__declspec(dllimport) void operator delete(void*); +__declspec(dllimport) inline int *ReferencingImportedNew() { return new int[2]; } +// MO1-DAG: define available_externally dllimport i32* @"\01?ReferencingImportedNew@@YAPAHXZ" +__declspec(dllimport) inline int *ReferencingImportedDelete() { delete (int*)nullptr; } +// MO1-DAG: define available_externally dllimport i32* @"\01?ReferencingImportedDelete@@YAPAHXZ" +USE(ReferencingImportedNew) +USE(ReferencingImportedDelete) + +// A dllimport function with a TLS variable must not be available_externally. +__declspec(dllimport) inline void FunctionWithTLSVar() { static __thread int x = 42; } +// MO1-DAG: declare dllimport void @"\01?FunctionWithTLSVar@@YAXXZ" +__declspec(dllimport) inline void FunctionWithNormalVar() { static int x = 42; } +// MO1-DAG: define available_externally dllimport void @"\01?FunctionWithNormalVar@@YAXXZ" +USE(FunctionWithTLSVar) +USE(FunctionWithNormalVar) //===----------------------------------------------------------------------===// |