summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp3
-rw-r--r--clang/lib/CodeGen/CGDeclCXX.cpp10
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp31
-rw-r--r--clang/lib/CodeGen/ItaniumCXXABI.cpp7
-rw-r--r--clang/lib/CodeGen/MicrosoftCXXABI.cpp12
-rw-r--r--clang/test/CodeGen/ms-declspecs.c4
-rw-r--r--clang/test/CodeGenCXX/cxx11-exception-spec.cpp16
-rw-r--r--clang/test/CodeGenCXX/dllexport-members.cpp32
-rw-r--r--clang/test/CodeGenCXX/dllexport.cpp48
-rw-r--r--clang/test/CodeGenCXX/dllimport.cpp2
-rw-r--r--clang/test/CodeGenCXX/ms-integer-static-data-members-exported.cpp4
-rw-r--r--clang/test/CodeGenCXX/ms-integer-static-data-members.cpp2
-rw-r--r--clang/test/CodeGenCXX/split-stacks.cpp4
-rw-r--r--clang/test/CodeGenCXX/static-init.cpp9
14 files changed, 100 insertions, 84 deletions
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 4a612c9bedf..39052e54ddd 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -206,6 +206,9 @@ llvm::Constant *CodeGenModule::getOrCreateStaticVarDecl(
GV->setAlignment(getContext().getDeclAlign(&D).getQuantity());
setGlobalVisibility(GV, &D);
+ if (supportsCOMDAT() && GV->isWeakForLinker())
+ GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
+
if (D.getTLSKind())
setTLSMode(GV, D);
diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp
index 0e3117400fe..12cdb950978 100644
--- a/clang/lib/CodeGen/CGDeclCXX.cpp
+++ b/clang/lib/CodeGen/CGDeclCXX.cpp
@@ -267,15 +267,7 @@ void CodeGenModule::EmitPointerToInitFunc(const VarDecl *D,
addUsedGlobal(PtrArray);
// If the GV is already in a comdat group, then we have to join it.
- llvm::Comdat *C = GV->getComdat();
-
- // LinkOnce and Weak linkage are lowered down to a single-member comdat group.
- // Make an explicit group so we can join it.
- if (!C && (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage())) {
- C = TheModule.getOrInsertComdat(GV->getName());
- GV->setComdat(C);
- }
- if (C)
+ if (llvm::Comdat *C = GV->getComdat())
PtrArray->setComdat(C);
}
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index a863591aa04..15d383418f2 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1928,6 +1928,31 @@ void CodeGenModule::MaybeHandleStaticInExternC(const SomeDecl *D,
R.first->second = nullptr;
}
+static bool shouldBeInCOMDAT(CodeGenModule &CGM, const Decl &D) {
+ if (!CGM.supportsCOMDAT())
+ return false;
+
+ if (D.hasAttr<SelectAnyAttr>())
+ return true;
+
+ GVALinkage Linkage;
+ if (auto *VD = dyn_cast<VarDecl>(&D))
+ Linkage = CGM.getContext().GetGVALinkageForVariable(VD);
+ else
+ Linkage = CGM.getContext().GetGVALinkageForFunction(cast<FunctionDecl>(&D));
+
+ switch (Linkage) {
+ case GVA_Internal:
+ case GVA_AvailableExternally:
+ case GVA_StrongExternal:
+ return false;
+ case GVA_DiscardableODR:
+ case GVA_StrongODR:
+ return true;
+ }
+ llvm_unreachable("No such linkage");
+}
+
void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
llvm::Constant *Init = nullptr;
QualType ASTTy = D->getType();
@@ -2071,6 +2096,9 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
setTLSMode(GV, *D);
}
+ if (shouldBeInCOMDAT(*this, *D))
+ GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
+
// Emit the initializer function if necessary.
if (NeedsGlobalCtor || NeedsGlobalDtor)
EmitCXXGlobalVarDeclInitFunc(D, GV, NeedsGlobalCtor);
@@ -2405,6 +2433,9 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD,
MaybeHandleStaticInExternC(D, Fn);
+ if (shouldBeInCOMDAT(*this, *D))
+ Fn->setComdat(TheModule.getOrInsertComdat(Fn->getName()));
+
CodeGenFunction(*this).GenerateCode(D, Fn, FI);
setFunctionDefinitionAttributes(D, Fn);
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index deebab85839..f2ffabcf3e9 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -1711,11 +1711,12 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
// The ABI says: It is suggested that it be emitted in the same COMDAT group
// as the associated data object
- if (!D.isLocalVarDecl() && var->isWeakForLinker() && CGM.supportsCOMDAT()) {
- llvm::Comdat *C = CGM.getModule().getOrInsertComdat(var->getName());
+ llvm::Comdat *C = var->getComdat();
+ if (!D.isLocalVarDecl() && C) {
guard->setComdat(C);
- var->setComdat(C);
CGF.CurFn->setComdat(C);
+ } else if (CGM.supportsCOMDAT() && guard->isWeakForLinker()) {
+ guard->setComdat(CGM.getModule().getOrInsertComdat(guard->getName()));
}
CGM.setStaticLocalDeclGuardAddress(&D, guard);
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 06c913e1ced..c80db7d18a1 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -1829,18 +1829,10 @@ void MicrosoftCXXABI::EmitThreadLocalInitFuncs(
llvm::Function *F = CXXThreadLocalInits[I];
// If the GV is already in a comdat group, then we have to join it.
- llvm::Comdat *C = GV->getComdat();
-
- // LinkOnce and Weak linkage are lowered down to a single-member comdat
- // group.
- // Make an explicit group so we can join it.
- if (!C && (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage())) {
- C = CGM.getModule().getOrInsertComdat(GV->getName());
- GV->setComdat(C);
+ if (llvm::Comdat *C = GV->getComdat())
AddToXDU(F)->setComdat(C);
- } else {
+ else
NonComdatInits.push_back(F);
- }
}
if (!NonComdatInits.empty()) {
diff --git a/clang/test/CodeGen/ms-declspecs.c b/clang/test/CodeGen/ms-declspecs.c
index 5dc7787b8fb..328fc835d34 100644
--- a/clang/test/CodeGen/ms-declspecs.c
+++ b/clang/test/CodeGen/ms-declspecs.c
@@ -2,8 +2,8 @@
__declspec(selectany) int x1 = 1;
const __declspec(selectany) int x2 = 2;
-// CHECK: @x1 = weak_odr global i32 1, align 4
-// CHECK: @x2 = weak_odr constant i32 2, align 4
+// CHECK: @x1 = weak_odr global i32 1, comdat, align 4
+// CHECK: @x2 = weak_odr constant i32 2, comdat, align 4
struct __declspec(align(16)) S {
char x;
diff --git a/clang/test/CodeGenCXX/cxx11-exception-spec.cpp b/clang/test/CodeGenCXX/cxx11-exception-spec.cpp
index 75f939f93f0..3fb5c15c2ab 100644
--- a/clang/test/CodeGenCXX/cxx11-exception-spec.cpp
+++ b/clang/test/CodeGenCXX/cxx11-exception-spec.cpp
@@ -22,9 +22,9 @@ template<> void S<short>::f() { h(); }
// CHECK: define {{.*}} @_ZN1SIA2_sE1fEv() [[NUW]]
template<> void S<short[2]>::f() noexcept { h(); }
-// CHECK: define {{.*}} @_Z1fIDsEvv() [[NONE]] {
+// CHECK: define {{.*}} @_Z1fIDsEvv() [[NONE]] comdat {
template void f<char16_t>();
-// CHECK: define {{.*}} @_Z1fIA2_DsEvv() [[NUW]] {
+// CHECK: define {{.*}} @_Z1fIA2_DsEvv() [[NUW]] comdat {
template void f<char16_t[2]>();
// CHECK: define {{.*}} @_ZN1SIDsE1fEv()
@@ -34,9 +34,9 @@ template void S<char16_t>::f();
template void S<char16_t[2]>::f();
void h() {
- // CHECK: define {{.*}} @_Z1fIiEvv() [[NUW]] {
+ // CHECK: define {{.*}} @_Z1fIiEvv() [[NUW]] comdat {
f<int>();
- // CHECK: define {{.*}} @_Z1fIA2_iEvv() [[NONE]] {
+ // CHECK: define {{.*}} @_Z1fIA2_iEvv() [[NONE]] comdat {
f<int[2]>();
// CHECK: define {{.*}} @_ZN1SIiE1fEv() [[NUW]]
@@ -45,9 +45,9 @@ void h() {
// CHECK-NOT: [[NUW]]
S<int[2]>::f();
- // CHECK: define {{.*}} @_Z1fIfEvv() [[NUW]] {
+ // CHECK: define {{.*}} @_Z1fIfEvv() [[NUW]] comdat {
void (*f1)() = &f<float>;
- // CHECK: define {{.*}} @_Z1fIdEvv() [[NONE]] {
+ // CHECK: define {{.*}} @_Z1fIdEvv() [[NONE]] comdat {
void (*f2)() = &f<double>;
// CHECK: define {{.*}} @_ZN1SIfE1fEv() [[NUW]]
@@ -56,9 +56,9 @@ void h() {
// CHECK-NOT: [[NUW]]
void (*f4)() = &S<double>::f;
- // CHECK: define {{.*}} @_Z1fIA4_cEvv() [[NUW]] {
+ // CHECK: define {{.*}} @_Z1fIA4_cEvv() [[NUW]] comdat {
(void)&f<char[4]>;
- // CHECK: define {{.*}} @_Z1fIcEvv() [[NONE]] {
+ // CHECK: define {{.*}} @_Z1fIcEvv() [[NONE]] comdat {
(void)&f<char>;
// CHECK: define {{.*}} @_ZN1SIA4_cE1fEv() [[NUW]]
diff --git a/clang/test/CodeGenCXX/dllexport-members.cpp b/clang/test/CodeGenCXX/dllexport-members.cpp
index d913c09ec7b..5b2af1e04bd 100644
--- a/clang/test/CodeGenCXX/dllexport-members.cpp
+++ b/clang/test/CodeGenCXX/dllexport-members.cpp
@@ -110,9 +110,9 @@ public:
// MSC-DAG: @"\01?StaticField@ExportMembers@@2HA" = dllexport global i32 1, align 4
// MSC-DAG: @"\01?StaticConstField@ExportMembers@@2HB" = dllexport constant i32 1, align 4
- // MSC-DAG: @"\01?StaticConstFieldEqualInit@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, align 4
- // MSC-DAG: @"\01?StaticConstFieldBraceInit@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, align 4
- // MSC-DAG: @"\01?ConstexprField@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, align 4
+ // MSC-DAG: @"\01?StaticConstFieldEqualInit@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4
+ // MSC-DAG: @"\01?StaticConstFieldBraceInit@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4
+ // MSC-DAG: @"\01?ConstexprField@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4
// GNU-DAG: @_ZN13ExportMembers11StaticFieldE = dllexport global i32 1, align 4
// GNU-DAG: @_ZN13ExportMembers16StaticConstFieldE = dllexport constant i32 1, align 4
// GNU-DAG: @_ZN13ExportMembers25StaticConstFieldEqualInitE = dllexport constant i32 1, align 4
@@ -233,9 +233,9 @@ public:
// MSC-DAG: @"\01?StaticField@Nested@ExportMembers@@2HA" = dllexport global i32 1, align 4
// MSC-DAG: @"\01?StaticConstField@Nested@ExportMembers@@2HB" = dllexport constant i32 1, align 4
- // MSC-DAG: @"\01?StaticConstFieldEqualInit@Nested@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, align 4
- // MSC-DAG: @"\01?StaticConstFieldBraceInit@Nested@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, align 4
- // MSC-DAG: @"\01?ConstexprField@Nested@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, align 4
+ // MSC-DAG: @"\01?StaticConstFieldEqualInit@Nested@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4
+ // MSC-DAG: @"\01?StaticConstFieldBraceInit@Nested@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4
+ // MSC-DAG: @"\01?ConstexprField@Nested@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4
// GNU-DAG: @_ZN13ExportMembers6Nested11StaticFieldE = dllexport global i32 1, align 4
// GNU-DAG: @_ZN13ExportMembers6Nested16StaticConstFieldE = dllexport constant i32 1, align 4
// GNU-DAG: @_ZN13ExportMembers6Nested25StaticConstFieldEqualInitE = dllexport constant i32 1, align 4
@@ -599,21 +599,21 @@ template<typename T> const int MemVarTmpl::StaticVar;
template<typename T> const int MemVarTmpl::ExportedStaticVar;
// Export implicit instantiation of an exported member variable template.
-// MSC-DAG: @"\01??$ExportedStaticVar@UImplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4
-// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ImplicitInst_ExportedEE = weak_odr dllexport constant i32 1, align 4
+// MSC-DAG: @"\01??$ExportedStaticVar@UImplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4
+// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ImplicitInst_ExportedEE = weak_odr dllexport constant i32 1, comdat, align 4
int useMemVarTmpl() { return MemVarTmpl::ExportedStaticVar<ImplicitInst_Exported>; }
// Export explicit instantiation declaration of an exported member variable
// template.
-// MSC-DAG: @"\01??$ExportedStaticVar@UExplicitDecl_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4
-// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ExplicitDecl_ExportedEE = weak_odr dllexport constant i32 1, align 4
+// MSC-DAG: @"\01??$ExportedStaticVar@UExplicitDecl_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4
+// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ExplicitDecl_ExportedEE = weak_odr dllexport constant i32 1, comdat, align 4
extern template const int MemVarTmpl::ExportedStaticVar<ExplicitDecl_Exported>;
template const int MemVarTmpl::ExportedStaticVar<ExplicitDecl_Exported>;
// Export explicit instantiation definition of an exported member variable
// template.
-// MSC-DAG: @"\01??$ExportedStaticVar@UExplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4
-// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ExplicitInst_ExportedEE = weak_odr dllexport constant i32 1, align 4
+// MSC-DAG: @"\01??$ExportedStaticVar@UExplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4
+// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ExplicitInst_ExportedEE = weak_odr dllexport constant i32 1, comdat, align 4
template const int MemVarTmpl::ExportedStaticVar<ExplicitInst_Exported>;
// Export specialization of an exported member variable template.
@@ -630,15 +630,15 @@ template<> const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_NotExported> = 1
// Export explicit instantiation declaration of a non-exported member variable
// template.
-// MSC-DAG: @"\01??$StaticVar@UExplicitDecl_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4
-// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitDecl_ExportedEE = weak_odr dllexport constant i32 1, align 4
+// MSC-DAG: @"\01??$StaticVar@UExplicitDecl_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4
+// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitDecl_ExportedEE = weak_odr dllexport constant i32 1, comdat, align 4
extern template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitDecl_Exported>;
template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitDecl_Exported>;
// Export explicit instantiation definition of a non-exported member variable
// template.
-// MSC-DAG: @"\01??$StaticVar@UExplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4
-// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitInst_ExportedEE = weak_odr dllexport constant i32 1, align 4
+// MSC-DAG: @"\01??$StaticVar@UExplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4
+// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitInst_ExportedEE = weak_odr dllexport constant i32 1, comdat, align 4
template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitInst_Exported>;
// Export specialization of a non-exported member variable template.
diff --git a/clang/test/CodeGenCXX/dllexport.cpp b/clang/test/CodeGenCXX/dllexport.cpp
index cfbc7e10078..93bd1f5fe99 100644
--- a/clang/test/CodeGenCXX/dllexport.cpp
+++ b/clang/test/CodeGenCXX/dllexport.cpp
@@ -110,43 +110,43 @@ template<typename T> __declspec(dllexport) int VarTmplImplicitDef;
USEVAR(VarTmplImplicitDef<ImplicitInst_Exported>)
// Export definition.
-// MSC-DAG: @"\01??$VarTmplInit1@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
-// GNU-DAG: @_Z12VarTmplInit1I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4
+// MSC-DAG: @"\01??$VarTmplInit1@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4
+// GNU-DAG: @_Z12VarTmplInit1I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, comdat, align 4
template<typename T> __declspec(dllexport) int VarTmplInit1 = 1;
INSTVAR(VarTmplInit1<ExplicitInst_Exported>)
-// MSC-DAG: @"\01??$VarTmplInit2@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
-// GNU-DAG: @_Z12VarTmplInit2I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4
+// MSC-DAG: @"\01??$VarTmplInit2@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4
+// GNU-DAG: @_Z12VarTmplInit2I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, comdat, align 4
template<typename T> int __declspec(dllexport) VarTmplInit2 = 1;
INSTVAR(VarTmplInit2<ExplicitInst_Exported>)
// Declare, then export definition.
-// MSC-DAG: @"\01??$VarTmplDeclInit@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
-// GNU-DAG: @_Z15VarTmplDeclInitI21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4
+// MSC-DAG: @"\01??$VarTmplDeclInit@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4
+// GNU-DAG: @_Z15VarTmplDeclInitI21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, comdat, align 4
template<typename T> __declspec(dllexport) extern int VarTmplDeclInit;
template<typename T> int VarTmplDeclInit = 1;
INSTVAR(VarTmplDeclInit<ExplicitInst_Exported>)
// Redeclarations
-// MSC-DAG: @"\01??$VarTmplRedecl1@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
-// GNU-DAG: @_Z14VarTmplRedecl1I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4
+// MSC-DAG: @"\01??$VarTmplRedecl1@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4
+// GNU-DAG: @_Z14VarTmplRedecl1I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, comdat, align 4
template<typename T> __declspec(dllexport) extern int VarTmplRedecl1;
template<typename T> __declspec(dllexport) int VarTmplRedecl1 = 1;
INSTVAR(VarTmplRedecl1<ExplicitInst_Exported>)
-// MSC-DAG: @"\01??$VarTmplRedecl2@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
-// GNU-DAG: @_Z14VarTmplRedecl2I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4
+// MSC-DAG: @"\01??$VarTmplRedecl2@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4
+// GNU-DAG: @_Z14VarTmplRedecl2I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, comdat, align 4
template<typename T> __declspec(dllexport) extern int VarTmplRedecl2;
template<typename T> int VarTmplRedecl2 = 1;
INSTVAR(VarTmplRedecl2<ExplicitInst_Exported>)
-// MSC-DAG: @"\01??$ExternalVarTmpl@UExplicitInst_Exported@@@ns@@3HA" = weak_odr dllexport global i32 1, align 4
-// GNU-DAG: @_ZN2ns15ExternalVarTmplI21ExplicitInst_ExportedEE = weak_odr dllexport global i32 1, align 4
+// MSC-DAG: @"\01??$ExternalVarTmpl@UExplicitInst_Exported@@@ns@@3HA" = weak_odr dllexport global i32 1, comdat, align 4
+// GNU-DAG: @_ZN2ns15ExternalVarTmplI21ExplicitInst_ExportedEE = weak_odr dllexport global i32 1, comdat, align 4
namespace ns { template<typename T> __declspec(dllexport) int ExternalVarTmpl = 1; }
INSTVAR(ns::ExternalVarTmpl<ExplicitInst_Exported>)
-// MSC-DAG: @"\01??$ExternalAutoTypeVarTmpl@UExplicitInst_Exported@@@@3UExternal@@A" = weak_odr dllexport global %struct.External zeroinitializer, align 4
-// GNU-DAG: @_Z23ExternalAutoTypeVarTmplI21ExplicitInst_ExportedE = weak_odr dllexport global %struct.External zeroinitializer, align 4
+// MSC-DAG: @"\01??$ExternalAutoTypeVarTmpl@UExplicitInst_Exported@@@@3UExternal@@A" = weak_odr dllexport global %struct.External zeroinitializer, comdat, align 4
+// GNU-DAG: @_Z23ExternalAutoTypeVarTmplI21ExplicitInst_ExportedE = weak_odr dllexport global %struct.External zeroinitializer, comdat, align 4
template<typename T> __declspec(dllexport) auto ExternalAutoTypeVarTmpl = External();
template External ExternalAutoTypeVarTmpl<ExplicitInst_Exported>;
@@ -155,19 +155,19 @@ template<typename T> int VarTmpl = 1;
template<typename T> __declspec(dllexport) int ExportedVarTmpl = 1;
// Export implicit instantiation of an exported variable template.
-// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
-// GNU-DAG: @_Z15ExportedVarTmplI21ImplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4
+// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4
+// GNU-DAG: @_Z15ExportedVarTmplI21ImplicitInst_ExportedE = weak_odr dllexport global i32 1, comdat, align 4
USEVAR(ExportedVarTmpl<ImplicitInst_Exported>)
// Export explicit instantiation declaration of an exported variable template.
-// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
-// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitDecl_ExportedE = weak_odr dllexport global i32 1, align 4
+// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4
+// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitDecl_ExportedE = weak_odr dllexport global i32 1, comdat, align 4
extern template int ExportedVarTmpl<ExplicitDecl_Exported>;
template int ExportedVarTmpl<ExplicitDecl_Exported>;
// Export explicit instantiation definition of an exported variable template.
-// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
-// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4
+// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4
+// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, comdat, align 4
template __declspec(dllexport) int ExportedVarTmpl<ExplicitInst_Exported>;
// Export specialization of an exported variable template.
@@ -187,14 +187,14 @@ template<> int ExportedVarTmpl<ExplicitSpec_NotExported>;
// Export explicit instantiation declaration of a non-exported variable template.
-// MSC-DAG: @"\01??$VarTmpl@UExplicitDecl_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
-// GNU-DAG: @_Z7VarTmplI21ExplicitDecl_ExportedE = weak_odr dllexport global i32 1, align 4
+// MSC-DAG: @"\01??$VarTmpl@UExplicitDecl_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4
+// GNU-DAG: @_Z7VarTmplI21ExplicitDecl_ExportedE = weak_odr dllexport global i32 1, comdat, align 4
extern template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>;
template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>;
// Export explicit instantiation definition of a non-exported variable template.
-// MSC-DAG: @"\01??$VarTmpl@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
-// GNU-DAG: @_Z7VarTmplI21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4
+// MSC-DAG: @"\01??$VarTmpl@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4
+// GNU-DAG: @_Z7VarTmplI21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, comdat, align 4
template __declspec(dllexport) int VarTmpl<ExplicitInst_Exported>;
// Export specialization of a non-exported variable template.
diff --git a/clang/test/CodeGenCXX/dllimport.cpp b/clang/test/CodeGenCXX/dllimport.cpp
index ddd390ad6f3..e5b9f64dcca 100644
--- a/clang/test/CodeGenCXX/dllimport.cpp
+++ b/clang/test/CodeGenCXX/dllimport.cpp
@@ -243,7 +243,7 @@ __declspec(dllimport) __attribute__((noinline)) inline void noinline() {}
USE(noinline)
// MSC2-NOT: @"\01?alwaysInline@@YAXXZ"()
-// GNU2-NOT: @_Z12alwaysInlinev()
+// GNU-DAG: define linkonce_odr void @_Z12alwaysInlinev() {{.*}} comdat {
__declspec(dllimport) __attribute__((always_inline)) inline void alwaysInline() {}
USE(alwaysInline)
diff --git a/clang/test/CodeGenCXX/ms-integer-static-data-members-exported.cpp b/clang/test/CodeGenCXX/ms-integer-static-data-members-exported.cpp
index 3f868f36ff6..78bb3a2b1af 100644
--- a/clang/test/CodeGenCXX/ms-integer-static-data-members-exported.cpp
+++ b/clang/test/CodeGenCXX/ms-integer-static-data-members-exported.cpp
@@ -17,6 +17,6 @@ struct __declspec(dllexport) S {
};
};
-// CHECK: @"\01?x@S@@2FB" = weak_odr dllexport constant i16 42, align 2
-// CHECK: @"\01?y@S@@2W4Enum@@B" = weak_odr dllexport constant i32 2, align 4
+// CHECK: @"\01?x@S@@2FB" = weak_odr dllexport constant i16 42, comdat, align 2
+// CHECK: @"\01?y@S@@2W4Enum@@B" = weak_odr dllexport constant i32 2, comdat, align 4
// CHECK-NOT: NonExported
diff --git a/clang/test/CodeGenCXX/ms-integer-static-data-members.cpp b/clang/test/CodeGenCXX/ms-integer-static-data-members.cpp
index b02b679d71a..4965f731918 100644
--- a/clang/test/CodeGenCXX/ms-integer-static-data-members.cpp
+++ b/clang/test/CodeGenCXX/ms-integer-static-data-members.cpp
@@ -26,7 +26,7 @@ const int S::x = 5;
// Inline initialization.
-// CHECK-INLINE: @"\01?x@S@@2HB" = linkonce_odr constant i32 5, align 4
+// CHECK-INLINE: @"\01?x@S@@2HB" = linkonce_odr constant i32 5, comdat, align 4
// Out-of-line initialization.
// CHECK-OUTOFLINE: @"\01?x@S@@2HB" = constant i32 5, align 4
diff --git a/clang/test/CodeGenCXX/split-stacks.cpp b/clang/test/CodeGenCXX/split-stacks.cpp
index 3e120344d6b..76e1b79b8f1 100644
--- a/clang/test/CodeGenCXX/split-stacks.cpp
+++ b/clang/test/CodeGenCXX/split-stacks.cpp
@@ -18,7 +18,7 @@ int nosplit() {
// CHECK-SEGSTK: define i32 @_Z3foov() [[SS:#[0-9]+]] {
// CHECK-SEGSTK: define i32 @_Z7nosplitv() [[NSS1:#[0-9]+]] {
-// CHECK-SEGSTK: define linkonce_odr i32 @_Z8tnosplitIiEiv() [[NSS2:#[0-9]+]] {
+// CHECK-SEGSTK: define linkonce_odr i32 @_Z8tnosplitIiEiv() [[NSS2:#[0-9]+]] comdat {
// CHECK-SEGSTK-NOT: [[NSS1]] = { {{.*}} "split-stack" {{.*}} }
// CHECK-SEGSTK-NOT: [[NSS2]] = { {{.*}} "split-stack" {{.*}} }
// CHECK-SEGSTK: [[SS]] = { {{.*}} "split-stack" {{.*}} }
@@ -27,7 +27,7 @@ int nosplit() {
// CHECK-NOSEGSTK: define i32 @_Z3foov() [[NSS0:#[0-9]+]] {
// CHECK-NOSEGSTK: define i32 @_Z7nosplitv() [[NSS1:#[0-9]+]] {
-// CHECK-NOSEGSTK: define linkonce_odr i32 @_Z8tnosplitIiEiv() [[NSS2:#[0-9]+]] {
+// CHECK-NOSEGSTK: define linkonce_odr i32 @_Z8tnosplitIiEiv() [[NSS2:#[0-9]+]] comdat {
// CHECK-NOSEGSTK-NOT: [[NSS1]] = { {{.*}} "split-stack" {{.*}} }
// CHECK-NOSEGSTK-NOT: [[NSS2]] = { {{.*}} "split-stack" {{.*}} }
// CHECK-NOSEGSTK-NOT: [[NSS3]] = { {{.*}} "split-stack" {{.*}} }
diff --git a/clang/test/CodeGenCXX/static-init.cpp b/clang/test/CodeGenCXX/static-init.cpp
index a9debe3de76..66ff5b3fbab 100644
--- a/clang/test/CodeGenCXX/static-init.cpp
+++ b/clang/test/CodeGenCXX/static-init.cpp
@@ -7,10 +7,8 @@
// CHECK: @_ZZN5test31BC1EvE1u = internal global { i8, [3 x i8] } { i8 97, [3 x i8] undef }, align 4
// CHECK: @_ZZN5test1L6getvarEiE3var = internal constant [4 x i32] [i32 1, i32 0, i32 2, i32 4], align 16
-// CHECK: @_ZZ2h2vE1i = linkonce_odr global i32 0
-// CHECK-NOT: comdat
-// CHECK: @_ZGVZ2h2vE1i = linkonce_odr global i64 0
-// CHECK-NOT: comdat
+// CHECK: @_ZZ2h2vE1i = linkonce_odr global i32 0, comdat, align
+// CHECK: @_ZGVZ2h2vE1i = linkonce_odr global i64 0, comdat{{$}}
struct A {
A();
@@ -37,8 +35,7 @@ void h() {
static const int i = a();
}
-// CHECK: define linkonce_odr void @_Z2h2v()
-// CHECK-NOT: comdat
+// CHECK: define linkonce_odr void @_Z2h2v() {{.*}} comdat {
inline void h2() {
static int i = a();
}
OpenPOWER on IntegriCloud