Skip to content

[Cygwin] Global symbols should be external by default #139797

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1689,7 +1689,7 @@ static bool shouldAssumeDSOLocal(const CodeGenModule &CGM,

const llvm::Triple &TT = CGM.getTriple();
const auto &CGOpts = CGM.getCodeGenOpts();
if (TT.isWindowsGNUEnvironment()) {
if (TT.isOSCygMing()) {
// 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.
Expand Down
2 changes: 2 additions & 0 deletions clang/test/CodeGen/dllexport.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-extensions -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple i686-windows-gnu -fms-extensions -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-windows-gnu -fms-extensions -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple i686-pc-cygwin -fms-extensions -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-pc-cygwin -fms-extensions -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes to this test do work even before this commit, so they're not directly related. So in theory we could also land such changes as a separate test-only patch. In this case it's quite a small extra test so it probably doesn't matter, but may be good to keep in mind in general.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry. I will be careful next time.




Expand Down
3 changes: 3 additions & 0 deletions clang/test/CodeGen/dllimport.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-extensions -emit-llvm -std=c11 -O0 -o - %s | FileCheck --check-prefix=CHECK --check-prefix=MS %s
// RUN: %clang_cc1 -triple i686-windows-gnu -fms-extensions -emit-llvm -std=c11 -O0 -o - %s | FileCheck --check-prefix=CHECK --check-prefix=GNU %s
// RUN: %clang_cc1 -triple x86_64-windows-gnu -fms-extensions -emit-llvm -std=c11 -O0 -o - %s | FileCheck --check-prefix=CHECK --check-prefix=GNU %s
// RUN: %clang_cc1 -triple i686-pc-cygwin -fms-extensions -emit-llvm -std=c11 -O0 -o - %s | FileCheck --check-prefix=CHECK --check-prefix=GNU %s
// RUN: %clang_cc1 -triple x86_64-pc-cygwin -fms-extensions -emit-llvm -std=c11 -O0 -o - %s | FileCheck --check-prefix=CHECK --check-prefix=GNU %s
// RUN: %clang_cc1 -triple i686-windows-msvc -fms-extensions -emit-llvm -std=c11 -O1 -fno-inline -o - %s | FileCheck --check-prefix=O1 --check-prefix=MO1 %s
// RUN: %clang_cc1 -triple i686-windows-gnu -fms-extensions -emit-llvm -std=c11 -O1 -fno-inline -o - %s | FileCheck --check-prefix=O1 --check-prefix=GO1 %s
// RUN: %clang_cc1 -triple i686-pc-cygwin -fms-extensions -emit-llvm -std=c11 -O1 -fno-inline -o - %s | FileCheck --check-prefix=O1 --check-prefix=GO1 %s

#define JOIN2(x, y) x##y
#define JOIN(x, y) JOIN2(x, y)
Expand Down
3 changes: 3 additions & 0 deletions clang/test/CodeGen/dso-local-executable.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
// RUN: %clang_cc1 -triple x86_64-w64-mingw32 -emit-llvm %s -o - | FileCheck --check-prefixes=MINGW,MINGW-NATIVE_TLS,MINGW-AUTO-IMPORT %s
// RUN: %clang_cc1 -triple x86_64-w64-mingw32 -emit-llvm %s -o - -fno-auto-import | FileCheck --check-prefixes=MINGW,MINGW-NATIVE_TLS,MINGW-NO-AUTO-IMPORT %s
// RUN: %clang_cc1 -triple x86_64-w64-mingw32 -emit-llvm %s -o - -femulated-tls | FileCheck --check-prefixes=MINGW,MINGW-EMUTLS,MINGW-AUTO-IMPORT %s
// RUN: %clang_cc1 -triple x86_64-pc-cygwin -emit-llvm %s -o - | FileCheck --check-prefixes=MINGW,MINGW-NATIVE_TLS,MINGW-AUTO-IMPORT %s
// RUN: %clang_cc1 -triple x86_64-pc-cygwin -emit-llvm %s -o - -fno-auto-import | FileCheck --check-prefixes=MINGW,MINGW-NATIVE_TLS,MINGW-NO-AUTO-IMPORT %s
// RUN: %clang_cc1 -triple x86_64-pc-cygwin -emit-llvm %s -o - -femulated-tls | FileCheck --check-prefixes=MINGW,MINGW-EMUTLS,MINGW-AUTO-IMPORT %s
// MINGW: @baz = dso_local global i32 42
// MINGW-NEXT: @import_var = external dllimport global i32
// MINGW-NEXT: @weak_bar = extern_weak global i32
Expand Down
30 changes: 27 additions & 3 deletions clang/test/CodeGenCXX/dllexport.cpp

Large diffs are not rendered by default.

104 changes: 101 additions & 3 deletions clang/test/CodeGenCXX/dllimport-members.cpp

Large diffs are not rendered by default.

30 changes: 26 additions & 4 deletions clang/test/CodeGenCXX/dllimport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@
// RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC --check-prefix=M64 %s
// RUN: %clang_cc1 -no-enable-noundef-analysis -triple i686-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=G32 %s
// RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU %s
// RUN: %clang_cc1 -no-enable-noundef-analysis -triple i686-pc-cygwin -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=C32 %s
// RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-pc-cygwin -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU %s
// RUN: %clang_cc1 -no-enable-noundef-analysis -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -fms-compatibility-version=18.00 -emit-llvm -std=c++1y -O1 -disable-llvm-passes -o - %s -DMSABI -w | FileCheck --check-prefix=MO1 --check-prefix=M18 %s
// RUN: %clang_cc1 -no-enable-noundef-analysis -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -fms-compatibility-version=19.00 -emit-llvm -std=c++1y -O1 -disable-llvm-passes -o - %s -DMSABI -w | FileCheck --check-prefix=MO1 --check-prefix=M19 %s
// RUN: %clang_cc1 -no-enable-noundef-analysis -triple i686-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O1 -disable-llvm-passes -o - %s -w | FileCheck --check-prefix=GO1 %s
// RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-scei-ps4 -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=PS %s
// RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-sie-ps5 -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=PS %s
// RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-scei-ps4 -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=PS %s
// RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-sie-ps5 -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=PS %s

// CHECK-NOT doesn't play nice with CHECK-DAG, so use separate run lines.
// RUN: %clang_cc1 -no-enable-noundef-analysis -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC2 %s
// RUN: %clang_cc1 -no-enable-noundef-analysis -triple i686-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU2 %s
// RUN: %clang_cc1 -no-enable-noundef-analysis -triple i686-pc-cygwin -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU2 %s

// Helper structs to make templates more expressive.
struct ImplicitInst_Imported {};
Expand Down Expand Up @@ -205,7 +208,7 @@ USEVAR(VarTmpl<ExplicitSpec_Imported>)
// Functions
//===----------------------------------------------------------------------===//

// GNU-DAG: declare dso_local void @_ZdlPv{{j|y}}(ptr, i{{32|64}})
// GNU-DAG: declare dso_local void @_ZdlPv{{[jym]}}(ptr, i{{32|64}})

// Import function declaration.
// MSC-DAG: declare dllimport void @"?decl@@YAXXZ"()
Expand Down Expand Up @@ -311,7 +314,7 @@ USE(friend5)

// Implicit declarations can be redeclared with dllimport.
// MSC-DAG: declare dllimport nonnull ptr @"??2@{{YAPAXI|YAPEAX_K}}@Z"(
// GNU-DAG: declare dllimport nonnull ptr @_Znw{{[yj]}}(
// GNU-DAG: declare dllimport nonnull ptr @_Znw{{[yjm]}}(
__declspec(dllimport) void* operator new(__SIZE_TYPE__ n);
void UNIQ(use)() { ::operator new(42); }

Expand Down Expand Up @@ -677,6 +680,7 @@ struct __declspec(dllimport) KeyFuncClass {
};
extern constexpr KeyFuncClass keyFuncClassVar = {};
// G32-DAG: @_ZTV12KeyFuncClass = external dllimport unnamed_addr constant { [3 x ptr] }
// C32-DAG: @_ZTV12KeyFuncClass = external dllimport unnamed_addr constant { [3 x ptr] }

struct __declspec(dllimport) X : public virtual W {};
USECLASS(X)
Expand Down Expand Up @@ -813,20 +817,23 @@ template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemp
USEMEMFUNC(PartiallySpecializedClassTemplate<void*>, f);
// M32-DAG: declare dso_local x86_thiscallcc void @"?f@?$PartiallySpecializedClassTemplate@PAX@@QAEXXZ"
// G32-DAG: declare dllimport x86_thiscallcc void @_ZN33PartiallySpecializedClassTemplateIPvE1fEv
// C32-DAG: declare dllimport void @_ZN33PartiallySpecializedClassTemplateIPvE1fEv

// Attributes on explicit specializations are honored.
template <typename T> struct ExplicitlySpecializedClassTemplate {};
template <> struct __declspec(dllimport) ExplicitlySpecializedClassTemplate<void*> { void f(); };
USEMEMFUNC(ExplicitlySpecializedClassTemplate<void*>, f);
// M32-DAG: declare dllimport x86_thiscallcc void @"?f@?$ExplicitlySpecializedClassTemplate@PAX@@QAEXXZ"
// G32-DAG: declare dllimport x86_thiscallcc void @_ZN34ExplicitlySpecializedClassTemplateIPvE1fEv
// C32-DAG: declare dllimport void @_ZN34ExplicitlySpecializedClassTemplateIPvE1fEv

// MS inherits DLL attributes to partial specializations.
template <typename T> struct __declspec(dllimport) PartiallySpecializedImportedClassTemplate {};
template <typename T> struct PartiallySpecializedImportedClassTemplate<T*> { void f() {} };
USEMEMFUNC(PartiallySpecializedImportedClassTemplate<void*>, f);
// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?f@?$PartiallySpecializedImportedClassTemplate@PAX@@QAEXXZ"
// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN41PartiallySpecializedImportedClassTemplateIPvE1fEv
// C32-DAG: define linkonce_odr dso_local void @_ZN41PartiallySpecializedImportedClassTemplateIPvE1fEv

// Attributes on the instantiation take precedence over attributes on the template.
template <typename T> struct __declspec(dllexport) ExplicitlyInstantiatedWithDifferentAttr { void f() {} };
Expand All @@ -842,6 +849,7 @@ USEMEMFUNC(ExplicitInstantiationDeclImportedDefTemplate<int>, f);
// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?f@?$ExplicitInstantiationDeclImportedDefTemplate@H@@QAEXXZ"
// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc ptr @"??0?$ExplicitInstantiationDeclImportedDefTemplate@H@@QAE@XZ"
// G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN44ExplicitInstantiationDeclImportedDefTemplateIiE1fEv
// C32-DAG: define weak_odr dso_local void @_ZN44ExplicitInstantiationDeclImportedDefTemplateIiE1fEv

template <typename T> struct __declspec(dllimport) ExplicitInstantiationDeclExportedDefImportedTemplate { void f() {} ExplicitInstantiationDeclExportedDefImportedTemplate() {} };
extern template struct __declspec(dllimport) ExplicitInstantiationDeclExportedDefImportedTemplate <int>;
Expand Down Expand Up @@ -919,20 +927,23 @@ struct __declspec(dllimport) DerivedFromTemplate : public ClassTemplate<int> {};
USEMEMFUNC(ClassTemplate<int>, func)
// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?func@?$ClassTemplate@H@@QAEXXZ"
// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ClassTemplateIiE4funcEv
// C32-DAG: define linkonce_odr dso_local void @_ZN13ClassTemplateIiE4funcEv
// PS-DAG: declare dllimport void @_ZN13ClassTemplateIiE4funcEv

// ImportedTemplate is explicitly imported.
struct __declspec(dllimport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
USEMEMFUNC(ImportedClassTemplate<int>, func)
// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ImportedClassTemplate@H@@QAEXXZ"
// G32-DAG: declare dllimport x86_thiscallcc void @_ZN21ImportedClassTemplateIiE4funcEv
// C32-DAG: declare dllimport void @_ZN21ImportedClassTemplateIiE4funcEv
// PS-DAG: declare dllimport void @_ZN21ImportedClassTemplateIiE4funcEv

// ExportedTemplate is explicitly exported.
struct __declspec(dllimport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
USEMEMFUNC(ExportedClassTemplate<int>, func)
// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$ExportedClassTemplate@H@@QAEXXZ"
// G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN21ExportedClassTemplateIiE4funcEv
// C32-DAG: define weak_odr dso_local dllexport void @_ZN21ExportedClassTemplateIiE4funcEv
// PS-DAG: define weak_odr dllexport void @_ZN21ExportedClassTemplateIiE4funcEv

// Base class already implicitly instantiated without attribute.
Expand All @@ -941,6 +952,7 @@ struct __declspec(dllimport) DerivedFromTemplateD2 : public ClassTemplate<double
USEMEMFUNC(ClassTemplate<double>, func)
// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ClassTemplate@N@@QAEXXZ"
// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ClassTemplateIdE4funcEv
// C32-DAG: define linkonce_odr dso_local void @_ZN13ClassTemplateIdE4funcEv
// PS-DAG: declare dllimport void @_ZN13ClassTemplateIdE4funcEv

// MS: Base class already instantiated with dfferent attribute.
Expand All @@ -949,48 +961,55 @@ struct __declspec(dllimport) DerivedFromTemplateB2 : public ClassTemplate<bool>
USEMEMFUNC(ClassTemplate<bool>, func)
// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$ClassTemplate@_N@@QAEXXZ"
// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ClassTemplateIbE4funcEv
// C32-DAG: define linkonce_odr dso_local void @_ZN13ClassTemplateIbE4funcEv
// PS-DAG: define weak_odr dllexport void @_ZN13ClassTemplateIbE4funcEv

// Base class already specialized without dll attribute.
struct __declspec(dllimport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
USEMEMFUNC(ExplicitlySpecializedTemplate<int>, func)
// M32-DAG: define linkonce_odr dso_local x86_thiscallcc void @"?func@?$ExplicitlySpecializedTemplate@H@@QAEXXZ"
// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv
// C32-DAG: define linkonce_odr dso_local void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv
// PS-DAG: define linkonce_odr void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv

// Base class alredy specialized with export attribute.
struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
USEMEMFUNC(ExplicitlyExportSpecializedTemplate<int>, func)
// M32-DAG: define dso_local dllexport x86_thiscallcc void @"?func@?$ExplicitlyExportSpecializedTemplate@H@@QAEXXZ"
// G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv
// C32-DAG: define dso_local dllexport void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv
// PS-DAG: define dso_local dllexport void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv

// Base class already specialized with import attribute.
struct __declspec(dllimport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
USEMEMFUNC(ExplicitlyImportSpecializedTemplate<int>, func)
// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ExplicitlyImportSpecializedTemplate@H@@QAEXXZ"
// G32-DAG: declare dllimport x86_thiscallcc void @_ZN35ExplicitlyImportSpecializedTemplateIiE4funcEv
// C32-DAG: declare dllimport void @_ZN35ExplicitlyImportSpecializedTemplateIiE4funcEv
// PS-DAG: declare dllimport void @_ZN35ExplicitlyImportSpecializedTemplateIiE4funcEv

// Base class already instantiated without dll attribute.
struct __declspec(dllimport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
USEMEMFUNC(ExplicitlyInstantiatedTemplate<int>, func)
// M32-DAG: define weak_odr dso_local x86_thiscallcc void @"?func@?$ExplicitlyInstantiatedTemplate@H@@QAEXXZ"
// G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN30ExplicitlyInstantiatedTemplateIiE4funcEv
// C32-DAG: define weak_odr dso_local void @_ZN30ExplicitlyInstantiatedTemplateIiE4funcEv
// PS-DAG: define weak_odr void @_ZN30ExplicitlyInstantiatedTemplateIiE4funcEv

// Base class already instantiated with export attribute.
struct __declspec(dllimport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
USEMEMFUNC(ExplicitlyExportInstantiatedTemplate<int>, func)
// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$ExplicitlyExportInstantiatedTemplate@H@@QAEXXZ"
// G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN36ExplicitlyExportInstantiatedTemplateIiE4funcEv
// C32-DAG: define weak_odr dso_local dllexport void @_ZN36ExplicitlyExportInstantiatedTemplateIiE4funcEv
// PS-DAG: define weak_odr dllexport void @_ZN36ExplicitlyExportInstantiatedTemplateIiE4funcEv

// Base class already instantiated with import attribute.
struct __declspec(dllimport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
USEMEMFUNC(ExplicitlyImportInstantiatedTemplate<int>, func)
// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ExplicitlyImportInstantiatedTemplate@H@@QAEXXZ"
// G32-DAG: declare dllimport x86_thiscallcc void @_ZN36ExplicitlyImportInstantiatedTemplateIiE4funcEv
// C32-DAG: declare dllimport void @_ZN36ExplicitlyImportInstantiatedTemplateIiE4funcEv
// PS-DAG: declare dllimport void @_ZN36ExplicitlyImportInstantiatedTemplateIiE4funcEv

// MS: A dll attribute propagates through multiple levels of instantiation.
Expand All @@ -1000,6 +1019,7 @@ struct __declspec(dllimport) BottomClass : public MiddleClass<int> { };
USEMEMFUNC(TopClass<int>, func)
// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?func@?$TopClass@H@@QAEXXZ"
// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN8TopClassIiE4funcEv
// C32-DAG: define linkonce_odr dso_local void @_ZN8TopClassIiE4funcEv
// PS-DAG: declare dllimport void @_ZN8TopClassIiE4funcEv

template <typename T> struct ExplicitInstantiationDeclTemplateBase { void func() {} };
Expand All @@ -1009,6 +1029,7 @@ template struct ExplicitInstantiationDeclTemplateBase<int>;
USEMEMFUNC(ExplicitInstantiationDeclTemplateBase<int>, func)
// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ExplicitInstantiationDeclTemplateBase@H@@QAEXXZ"
// G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN37ExplicitInstantiationDeclTemplateBaseIiE4funcEv
// C32-DAG: define weak_odr dso_local void @_ZN37ExplicitInstantiationDeclTemplateBaseIiE4funcEv
// PS-DAG: declare dllimport void @_ZN37ExplicitInstantiationDeclTemplateBaseIiE4funcEv

template <typename T> struct ExplicitInstantiationDeclTemplateBase2 { void func() {} };
Expand All @@ -1018,6 +1039,7 @@ template struct __declspec(dllexport) ExplicitInstantiationDeclTemplateBase2<int
USEMEMFUNC(ExplicitInstantiationDeclTemplateBase2<int>, func)
// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ExplicitInstantiationDeclTemplateBase2@H@@QAEXXZ"
// G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN38ExplicitInstantiationDeclTemplateBase2IiE4funcEv
// C32-DAG: define weak_odr dso_local void @_ZN38ExplicitInstantiationDeclTemplateBase2IiE4funcEv
// PS-DAG: declare dllimport void @_ZN38ExplicitInstantiationDeclTemplateBase2IiE4funcEv

namespace pr39496 {
Expand Down
1 change: 1 addition & 0 deletions clang/test/CodeGenCXX/dso-local-executable.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// RUN: %clang_cc1 -triple x86_64-pc-linux -mrelocation-model static -O1 -disable-llvm-passes -emit-llvm %s -o - | FileCheck --check-prefix=STATIC %s
// RUN: %clang_cc1 -triple x86_64-pc-linux -mrelocation-model static -fno-plt -O1 -disable-llvm-passes -emit-llvm %s -o - | FileCheck --check-prefix=NOPLT %s
// RUN: %clang_cc1 -triple x86_64-w64-mingw32 -O1 -disable-llvm-passes -emit-llvm %s -o - | FileCheck --check-prefix=MINGW %s
// RUN: %clang_cc1 -triple x86_64-pc-cygwin -O1 -disable-llvm-passes -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
Expand Down