From c510fac5695e904b43d5bf0feee31cc9550f110e Mon Sep 17 00:00:00 2001 From: Martin Storsjo Date: Wed, 29 Aug 2018 17:26:58 +0000 Subject: [PATCH] [MinGW] Don't mark external variables as DSO local Since MinGW supports automatically importing external variables from DLLs even without the DLLImport attribute, we shouldn't mark them as DSO local unless we actually know them to be local for sure. Keep marking thread local variables as DSO local. Differential Revision: https://reviews.llvm.org/D51382 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@340941 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CodeGenModule.cpp | 8 ++++++++ test/CodeGen/dllimport.c | 3 ++- test/CodeGen/dso-local-executable.c | 11 +++++++++++ test/CodeGenCXX/dllexport.cpp | 4 ++-- test/CodeGenCXX/dllimport-members.cpp | 2 +- test/CodeGenCXX/dllimport.cpp | 4 ++-- test/CodeGenCXX/dso-local-executable.cpp | 18 ++++++++++++++++++ 7 files changed, 44 insertions(+), 6 deletions(-) diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 29692eedb5..c5cac6a398 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -730,6 +730,14 @@ static bool shouldAssumeDSOLocal(const CodeGenModule &CGM, return false; const llvm::Triple &TT = CGM.getTriple(); + if (TT.isWindowsGNUEnvironment()) { + // In MinGW, variables without DLLImport can still be automatically + // imported from a DLL by the linker; don't mark variables that + // potentially could come from another DLL as DSO local. + if (GV->isDeclarationForLinker() && isa(GV) && + !GV->isThreadLocal()) + return false; + } // Every other GV is local on COFF. // Make an exception for windows OS in the triple: Some firmware builds use // *-win32-macho triples. This (accidentally?) produced windows relocations diff --git a/test/CodeGen/dllimport.c b/test/CodeGen/dllimport.c index 61d6957052..c3fd0770ee 100644 --- a/test/CodeGen/dllimport.c +++ b/test/CodeGen/dllimport.c @@ -39,7 +39,8 @@ USEVAR(GlobalRedecl2) // NB: MSVC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC // and drop the dllimport with a warning. -// CHECK: @GlobalRedecl3 = external dso_local global i32 +// MS: @GlobalRedecl3 = external dso_local global i32 +// GNU: @GlobalRedecl3 = external global i32 __declspec(dllimport) extern int GlobalRedecl3; extern int GlobalRedecl3; // dllimport ignored USEVAR(GlobalRedecl3) diff --git a/test/CodeGen/dso-local-executable.c b/test/CodeGen/dso-local-executable.c index 6e434a67ef..36fd4d0d03 100644 --- a/test/CodeGen/dso-local-executable.c +++ b/test/CodeGen/dso-local-executable.c @@ -9,6 +9,17 @@ // COFF-DAG: @import_var = external dllimport global i32 // COFF-DAG: declare dllimport void @import_func() +// RUN: %clang_cc1 -triple x86_64-w64-mingw32 -emit-llvm %s -o - | FileCheck -allow-deprecated-dag-overlap --check-prefix=MINGW %s +// MINGW-DAG: @bar = external global i32 +// MINGW-DAG: @weak_bar = extern_weak global i32 +// MINGW-DAG: declare dso_local void @foo() +// MINGW-DAG: @baz = dso_local global i32 42 +// MINGW-DAG: define dso_local i32* @zed() +// MINGW-DAG: @thread_var = external dso_local thread_local global i32 +// MINGW-DAG: @local_thread_var = dso_local thread_local global i32 42 +// MINGW-DAG: @import_var = external dllimport global i32 +// MINGW-DAG: declare dllimport void @import_func() + // RUN: %clang_cc1 -triple x86_64-pc-linux -emit-llvm -mrelocation-model static %s -o - | FileCheck -allow-deprecated-dag-overlap --check-prefix=STATIC %s // STATIC-DAG: @bar = external dso_local global i32 // STATIC-DAG: @weak_bar = extern_weak dso_local global i32 diff --git a/test/CodeGenCXX/dllexport.cpp b/test/CodeGenCXX/dllexport.cpp index 5e4aa013b3..392df84da1 100644 --- a/test/CodeGenCXX/dllexport.cpp +++ b/test/CodeGenCXX/dllexport.cpp @@ -43,7 +43,7 @@ __declspec(dllexport) extern int ExternGlobalDecl; // M64-DAG: @__ImageBase = external dso_local constant i8 -// GNU-DAG: @_ZTVN10__cxxabiv117__class_type_infoE = external dso_local global +// GNU-DAG: @_ZTVN10__cxxabiv117__class_type_infoE = external global // dllexport implies a definition. // MSC-DAG: @"?GlobalDef@@3HA" = dso_local dllexport global i32 0, align 4 @@ -137,7 +137,7 @@ class __declspec(dllexport) i : h<> {}; // Declarations are not exported. // MSC-DAG: @"??$VarTmplImplicitDef@UImplicitInst_Exported@@@@3HA" = external dso_local global -// GNU-DAG: @_Z18VarTmplImplicitDefI21ImplicitInst_ExportedE = external dso_local global +// GNU-DAG: @_Z18VarTmplImplicitDefI21ImplicitInst_ExportedE = external global template __declspec(dllexport) extern int VarTmplImplicitDef; USEVAR(VarTmplImplicitDef) diff --git a/test/CodeGenCXX/dllimport-members.cpp b/test/CodeGenCXX/dllimport-members.cpp index 7a7519f668..f8034cfb47 100644 --- a/test/CodeGenCXX/dllimport-members.cpp +++ b/test/CodeGenCXX/dllimport-members.cpp @@ -854,7 +854,7 @@ USEMV(MemVarTmpl, ImportedStaticVar) // Not importing specialization of a member variable template without explicit // dllimport. // MSC-DAG: @"??$ImportedStaticVar@UExplicitSpec_NotImported@@@MemVarTmpl@@2HB" = external dso_local constant i32 -// GNU-DAG: @_ZN10MemVarTmpl17ImportedStaticVarI24ExplicitSpec_NotImportedEE = external dso_local constant i32 +// GNU-DAG: @_ZN10MemVarTmpl17ImportedStaticVarI24ExplicitSpec_NotImportedEE = external constant i32 template<> const int MemVarTmpl::ImportedStaticVar; USEMV(MemVarTmpl, ImportedStaticVar) diff --git a/test/CodeGenCXX/dllimport.cpp b/test/CodeGenCXX/dllimport.cpp index 74f58cc3b1..a6345be9ad 100644 --- a/test/CodeGenCXX/dllimport.cpp +++ b/test/CodeGenCXX/dllimport.cpp @@ -78,7 +78,7 @@ USEVAR(GlobalRedecl2c) // NB: MSC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC // and drop the dllimport with a warning. // MSC-DAG: @"?GlobalRedecl3@@3HA" = external dso_local global i32 -// GNU-DAG: @GlobalRedecl3 = external dso_local global i32 +// GNU-DAG: @GlobalRedecl3 = external global i32 __declspec(dllimport) extern int GlobalRedecl3; extern int GlobalRedecl3; // dllimport ignored USEVAR(GlobalRedecl3) @@ -137,7 +137,7 @@ template __declspec(dllimport) int VarTmplRedecl2; USEVAR(VarTmplRedecl2) // MSC-DAG: @"??$VarTmplRedecl3@UImplicitInst_Imported@@@@3HA" = external dso_local global i32 -// GNU-DAG: @_Z14VarTmplRedecl3I21ImplicitInst_ImportedE = external dso_local global i32 +// GNU-DAG: @_Z14VarTmplRedecl3I21ImplicitInst_ImportedE = external global i32 template __declspec(dllimport) extern int VarTmplRedecl3; template extern int VarTmplRedecl3; // dllimport ignored USEVAR(VarTmplRedecl3) diff --git a/test/CodeGenCXX/dso-local-executable.cpp b/test/CodeGenCXX/dso-local-executable.cpp index cc8d50f09c..ceb649e074 100644 --- a/test/CodeGenCXX/dso-local-executable.cpp +++ b/test/CodeGenCXX/dso-local-executable.cpp @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -triple x86_64-pc-linux -mrelocation-model static -O1 -emit-llvm %s -o - | FileCheck --check-prefix=STATIC %s // RUN: %clang_cc1 -triple x86_64-pc-linux -mrelocation-model static -fno-plt -O1 -emit-llvm %s -o - | FileCheck --check-prefix=NOPLT %s +// RUN: %clang_cc1 -triple x86_64-w64-mingw32 -O1 -emit-llvm %s -o - | FileCheck --check-prefix=MINGW %s // STATIC-DAG: @_ZTV1C = linkonce_odr dso_local unnamed_addr constant // STATIC-DAG: @_ZTS1C = linkonce_odr dso_local constant @@ -19,6 +20,15 @@ // NOPLT-DAG: define dso_local void @_ZN1CC1Ev( // NOPLT-DAG: define linkonce_odr dso_local void @_ZN1C3fooEv( +// MINGW-DAG: @_ZTV1C = linkonce_odr dso_local unnamed_addr constant +// MINGW-DAG: @_ZTS1C = linkonce_odr dso_local constant +// MINGW-DAG: @_ZTI1C = linkonce_odr dso_local constant +// MINGW-DAG: @_ZZ14useStaticLocalvE3obj = linkonce_odr dso_local global +// MINGW-DAG: @_ZGVZN5guard1gEvE1a = linkonce_odr dso_local global +// MINGW-DAG: define dso_local void @_ZN1CC2Ev( +// MINGW-DAG: define dso_local void @_ZN1CC1Ev( +// MINGW-DAG: define linkonce_odr dso_local void @_ZN1C3fooEv( + struct C { C(); virtual void foo() {} @@ -48,15 +58,23 @@ int h() { } // namespace guard +// STATIC-DAG: @_ZN5test23barIiE1xE = available_externally dso_local constant i32 // STATIC-DAG: define available_externally dso_local void @_ZN5test23barIcEC1Ev( +// NOPLT-DAG: @_ZN5test23barIiE1xE = available_externally dso_local constant i32 // NOPLT-DAG: define available_externally void @_ZN5test23barIcEC1Ev( +// MINGW-DAG: @_ZN5test23barIiE1xE = available_externally constant i32 +// MINGW-DAG: define available_externally dso_local void @_ZN5test23barIcEC1Ev( namespace test2 { void foo(); template struct bar { virtual void zed(); + static const int x = 42; bar() { foo(); } }; extern template class bar; bar abc; +const int *getX() { + return &bar::x; +} } // namespace test2 -- 2.40.0