[clang] [clang] Do not emit template parameter objects as COMDATs when they have internal linkage. (PR #125448)
https://github.com/resistor closed https://github.com/llvm/llvm-project/pull/125448 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Do not emit template parameter objects as COMDATs when they have internal linkage. (PR #125448)
https://github.com/alexander-shaposhnikov approved this pull request. https://github.com/llvm/llvm-project/pull/125448 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Do not emit template parameter objects as COMDATs when they have internal linkage. (PR #125448)
https://github.com/resistor updated
https://github.com/llvm/llvm-project/pull/125448
>From 8d2ed55358510e45c03934aaaffccbf12d0bffce Mon Sep 17 00:00:00 2001
From: Owen Anderson
Date: Mon, 3 Feb 2025 15:41:20 +1300
Subject: [PATCH] [clang] Do not emit template parameter objects as COMDATs
when they have internal linkage.
Per the ELF spec, section groups may only contain local symbols if those
symbols are only
referenced from within the section group. [1] In the case of template parameter
objects,
they can be referenced from outside the group when the type of the object was
declared
in an anonymous namespace. In that case, we can't place the object in a COMDAT.
This matches
GCC's linkage behavior on the test input.
[1]: https://www.sco.com/developers/gabi/latest/ch4.sheader.html#section_groups
---
clang/lib/CodeGen/CodeGenModule.cpp | 2 +-
clang/test/CodeGenCXX/template-param-objects.cpp | 10 ++
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp
b/clang/lib/CodeGen/CodeGenModule.cpp
index 05879cd486a8c9..82002b8d8e4d4f 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -3765,7 +3765,7 @@ ConstantAddress
CodeGenModule::GetAddrOfTemplateParamObject(
auto *GV = new llvm::GlobalVariable(getModule(), Init->getType(),
/*isConstant=*/true, Linkage, Init,
Name);
setGVProperties(GV, TPO);
- if (supportsCOMDAT())
+ if (supportsCOMDAT() && Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
Emitter.finalize(GV);
diff --git a/clang/test/CodeGenCXX/template-param-objects.cpp
b/clang/test/CodeGenCXX/template-param-objects.cpp
index 11ebd21521e83b..ff6acc438d137a 100644
--- a/clang/test/CodeGenCXX/template-param-objects.cpp
+++ b/clang/test/CodeGenCXX/template-param-objects.cpp
@@ -5,6 +5,9 @@ struct S { char buf[32]; };
template constexpr const char *begin() { return s.buf; }
template constexpr const char *end() { return s.buf +
__builtin_strlen(s.buf); }
+namespace { struct T { char buf[32]; }; }
+template constexpr const char* begin_anon() { return t.buf; }
+
// ITANIUM:
[[HELLO:@_ZTAXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100]]
// MSABI:
[[HELLO:@"[?][?]__N2US@@3D0GI@@0GF@@0GM@@0GM@@0GP@@0CA@@0HH@@0GP@@0HC@@0GM@@0GE@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@"]]
// ITANIUM-SAME: = linkonce_odr constant { <{ [11 x i8], [21 x i8] }> } { <{
[11 x i8], [21 x i8] }> <{ [11 x i8] c"hello world", [21 x i8] zeroinitializer
}> }, comdat
@@ -19,3 +22,10 @@ const char *p = begin();
// MSABI: @"?q@@3PEBDEB"
// CHECK-SAME: global ptr getelementptr (i8, ptr [[HELLO]], i64 11)
const char *q = end();
+
+
+// CHECK: internal constant { <{ [10 x i8], [22 x i8] }> } { <{ [10 x i8], [22
x i8] }> <{ [10 x i8] c"hello anon", [22 x i8] zeroinitializer }> }
+// CHECK-NOT: comdat
+// ITANIUM: @r
+// MSABI: @"?r@@3PEBDEB"
+const char *r = begin_anon();
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Do not emit template parameter objects as COMDATs when they have internal linkage. (PR #125448)
https://github.com/resistor updated
https://github.com/llvm/llvm-project/pull/125448
>From b3078fa4389f6be3f0b8c463ab9e79f1b4a9d23b Mon Sep 17 00:00:00 2001
From: Owen Anderson
Date: Mon, 3 Feb 2025 15:41:20 +1300
Subject: [PATCH] [clang] Do not emit template parameter objects as COMDATs
when they have internal linkage.
Per the ELF spec, section groups may only contain local symbols if those
symbols are only
referenced from within the section group. [1] In the case of template parameter
objects,
they can be referenced from outside the group when the type of the object was
declared
in an anonymous namespace. In that case, we can't place the object in a COMDAT.
This matches
GCC's linkage behavior on the test input.
[1]: https://www.sco.com/developers/gabi/latest/ch4.sheader.html#section_groups
---
clang/lib/CodeGen/CodeGenModule.cpp | 2 +-
clang/test/CodeGenCXX/template-param-objects.cpp | 13 +
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp
b/clang/lib/CodeGen/CodeGenModule.cpp
index 05879cd486a8c9..82002b8d8e4d4f 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -3765,7 +3765,7 @@ ConstantAddress
CodeGenModule::GetAddrOfTemplateParamObject(
auto *GV = new llvm::GlobalVariable(getModule(), Init->getType(),
/*isConstant=*/true, Linkage, Init,
Name);
setGVProperties(GV, TPO);
- if (supportsCOMDAT())
+ if (supportsCOMDAT() && Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
Emitter.finalize(GV);
diff --git a/clang/test/CodeGenCXX/template-param-objects.cpp
b/clang/test/CodeGenCXX/template-param-objects.cpp
index 11ebd21521e83b..4b78e1e84f8638 100644
--- a/clang/test/CodeGenCXX/template-param-objects.cpp
+++ b/clang/test/CodeGenCXX/template-param-objects.cpp
@@ -5,6 +5,9 @@ struct S { char buf[32]; };
template constexpr const char *begin() { return s.buf; }
template constexpr const char *end() { return s.buf +
__builtin_strlen(s.buf); }
+namespace { struct T { char buf[32]; }; }
+template constexpr const char* begin_anon() { return t.buf; }
+
// ITANIUM:
[[HELLO:@_ZTAXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100]]
// MSABI:
[[HELLO:@"[?][?]__N2US@@3D0GI@@0GF@@0GM@@0GM@@0GP@@0CA@@0HH@@0GP@@0HC@@0GM@@0GE@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@"]]
// ITANIUM-SAME: = linkonce_odr constant { <{ [11 x i8], [21 x i8] }> } { <{
[11 x i8], [21 x i8] }> <{ [11 x i8] c"hello world", [21 x i8] zeroinitializer
}> }, comdat
@@ -19,3 +22,13 @@ const char *p = begin();
// MSABI: @"?q@@3PEBDEB"
// CHECK-SAME: global ptr getelementptr (i8, ptr [[HELLO]], i64 11)
const char *q = end();
+
+
+// ITANIUM:
[[HELLOANON:@_ZTAXtlN12_GLOBAL__N_11TEtlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc97ELc110ELc111ELc110]]
+// MSABI:
[[HELLOANON:@"\?\?__N2UT@\?A0xFD1119C8@@3D0GI@@0GF@@0GM@@0GM@@0GP@@0CA@@0GB@@0GO@@0GP@@0GO@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@"]]
+// CHECK-SAME: internal constant { <{ [10 x i8], [22 x i8] }> } { <{ [10 x
i8], [22 x i8] }> <{ [10 x i8] c"hello anon", [22 x i8] zeroinitializer }> }
+// ITANIUM: @r
+// MSABI: @"?r@@3PEBDEB"
+// CHECK-SAME: global ptr [[HELLOANON]]
+// CHECK-NOT: comdat
+const char *r = begin_anon();
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Do not emit template parameter objects as COMDATs when they have internal linkage. (PR #125448)
https://github.com/MaskRay approved this pull request. https://github.com/llvm/llvm-project/pull/125448 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Do not emit template parameter objects as COMDATs when they have internal linkage. (PR #125448)
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -emit-llvm -std=c++20 -triple x86_64-unknown-linux-gnu %s
-o - | FileCheck %s
+
+// COMDAT groups in ELF objects are not permitted to contain local symbols.
While template parameter
+// objects are normally emitted in COMDATs, we shouldn't do so if they would
have internal linkage.
+
+extern "C" int printf(...);
+typedef __typeof__(sizeof(0)) size_t;
+
+namespace {
+template
+struct DebugContext
+{
+char value[N];
+constexpr DebugContext(const char (&str)[N]) {
resistor wrote:
Done and folded into existing test.
https://github.com/llvm/llvm-project/pull/125448
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Do not emit template parameter objects as COMDATs when they have internal linkage. (PR #125448)
@@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -emit-llvm -std=c++20 -triple x86_64-unknown-linux-gnu %s -o - | FileCheck %s resistor wrote: Done https://github.com/llvm/llvm-project/pull/125448 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Do not emit template parameter objects as COMDATs when they have internal linkage. (PR #125448)
https://github.com/resistor updated
https://github.com/llvm/llvm-project/pull/125448
>From fabd1f091d018e76d59777ce29a9d16ef6abb48f Mon Sep 17 00:00:00 2001
From: Owen Anderson
Date: Mon, 3 Feb 2025 15:41:20 +1300
Subject: [PATCH] [clang] Do not emit template parameter objects as COMDATs
when they have internal linkage.
Per the ELF spec, section groups may only contain local symbols if those
symbols are only
referenced from within the section group. [1] In the case of template parameter
objects,
they can be referenced from outside the group when the type of the object was
declared
in an anonymous namespace. In that case, we can't place the object in a COMDAT.
This matches
GCC's linkage behavior on the test input.
[1]: https://www.sco.com/developers/gabi/latest/ch4.sheader.html#section_groups
---
clang/lib/CodeGen/CodeGenModule.cpp | 2 +-
clang/test/CodeGenCXX/template-param-objects.cpp | 13 +
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp
b/clang/lib/CodeGen/CodeGenModule.cpp
index 05879cd486a8c9..82002b8d8e4d4f 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -3765,7 +3765,7 @@ ConstantAddress
CodeGenModule::GetAddrOfTemplateParamObject(
auto *GV = new llvm::GlobalVariable(getModule(), Init->getType(),
/*isConstant=*/true, Linkage, Init,
Name);
setGVProperties(GV, TPO);
- if (supportsCOMDAT())
+ if (supportsCOMDAT() && Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
Emitter.finalize(GV);
diff --git a/clang/test/CodeGenCXX/template-param-objects.cpp
b/clang/test/CodeGenCXX/template-param-objects.cpp
index 11ebd21521e83b..afe68c034def22 100644
--- a/clang/test/CodeGenCXX/template-param-objects.cpp
+++ b/clang/test/CodeGenCXX/template-param-objects.cpp
@@ -5,6 +5,9 @@ struct S { char buf[32]; };
template constexpr const char *begin() { return s.buf; }
template constexpr const char *end() { return s.buf +
__builtin_strlen(s.buf); }
+namespace { struct T { char buf[32]; }; }
+template constexpr const char* begin_anon() { return t.buf; }
+
// ITANIUM:
[[HELLO:@_ZTAXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100]]
// MSABI:
[[HELLO:@"[?][?]__N2US@@3D0GI@@0GF@@0GM@@0GM@@0GP@@0CA@@0HH@@0GP@@0HC@@0GM@@0GE@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@"]]
// ITANIUM-SAME: = linkonce_odr constant { <{ [11 x i8], [21 x i8] }> } { <{
[11 x i8], [21 x i8] }> <{ [11 x i8] c"hello world", [21 x i8] zeroinitializer
}> }, comdat
@@ -19,3 +22,13 @@ const char *p = begin();
// MSABI: @"?q@@3PEBDEB"
// CHECK-SAME: global ptr getelementptr (i8, ptr [[HELLO]], i64 11)
const char *q = end();
+
+
+// ITANIUM:
[[HELLOANON:@_ZTAXtlN12_GLOBAL__N_11TEtlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc97ELc110ELc111ELc110]]
+// MSABI:
[[HELLOANON:@"[?][?]__N2UT@[?]A0xFD1119C8@@3D0GI@@0GF@@0GM@@0GM@@0GP@@0CA@@0GB@@0GO@@0GP@@0GO@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@"]]
+// CHECK-SAME: internal constant { <{ [10 x i8], [22 x i8] }> } { <{ [10 x
i8], [22 x i8] }> <{ [10 x i8] c"hello anon", [22 x i8] zeroinitializer }> }
+// ITANIUM: @r
+// MSABI: @"?r@@3PEBDEB"
+// CHECK-SAME: global ptr [[HELLOANON]]
+// CHECK-NOT: comdat
+const char *r = begin_anon();
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Do not emit template parameter objects as COMDATs when they have internal linkage. (PR #125448)
@@ -3765,7 +3765,7 @@ ConstantAddress CodeGenModule::GetAddrOfTemplateParamObject( auto *GV = new llvm::GlobalVariable(getModule(), Init->getType(), /*isConstant=*/true, Linkage, Init, Name); setGVProperties(GV, TPO); - if (supportsCOMDAT()) + if (supportsCOMDAT() && Linkage == llvm::GlobalValue::LinkOnceODRLinkage) resistor wrote: Linkage is set to either LinkOnceODRLinkage or InternalLinkage a few lines above this. https://github.com/llvm/llvm-project/pull/125448 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Do not emit template parameter objects as COMDATs when they have internal linkage. (PR #125448)
@@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -emit-llvm -std=c++20 -triple x86_64-unknown-linux-gnu %s -o - | FileCheck %s MaskRay wrote: Probably best to figure out where the primary test of the neighbor lines is and adds the extra test there. https://github.com/llvm/llvm-project/pull/125448 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Do not emit template parameter objects as COMDATs when they have internal linkage. (PR #125448)
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -emit-llvm -std=c++20 -triple x86_64-unknown-linux-gnu %s
-o - | FileCheck %s
+
+// COMDAT groups in ELF objects are not permitted to contain local symbols.
While template parameter
+// objects are normally emitted in COMDATs, we shouldn't do so if they would
have internal linkage.
+
+extern "C" int printf(...);
+typedef __typeof__(sizeof(0)) size_t;
+
+namespace {
+template
+struct DebugContext
+{
+char value[N];
+constexpr DebugContext(const char (&str)[N]) {
MaskRay wrote:
The test can be reduced.
https://github.com/llvm/llvm-project/pull/125448
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Do not emit template parameter objects as COMDATs when they have internal linkage. (PR #125448)
@@ -3765,7 +3765,7 @@ ConstantAddress CodeGenModule::GetAddrOfTemplateParamObject( auto *GV = new llvm::GlobalVariable(getModule(), Init->getType(), /*isConstant=*/true, Linkage, Init, Name); setGVProperties(GV, TPO); - if (supportsCOMDAT()) + if (supportsCOMDAT() && Linkage == llvm::GlobalValue::LinkOnceODRLinkage) MaskRay wrote: I recall that in some cases WeakODRLinkage is used. Should the condition be something like `!isLocalLinkage()`? https://github.com/llvm/llvm-project/pull/125448 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Do not emit template parameter objects as COMDATs when they have internal linkage. (PR #125448)
llvmbot wrote:
@llvm/pr-subscribers-clang
Author: Owen Anderson (resistor)
Changes
Per the ELF spec, section groups may only contain local symbols if those
symbols are only
referenced from within the section group. [1] In the case of template parameter
objects,
they can be referenced from outside the group when the type of the object was
declared
in an anonymous namespace. In that case, we can't place the object in a COMDAT.
This matches
GCC's linkage behavior on the test input.
[1]: https://www.sco.com/developers/gabi/latest/ch4.sheader.html#section_groups
---
Full diff: https://github.com/llvm/llvm-project/pull/125448.diff
2 Files Affected:
- (modified) clang/lib/CodeGen/CodeGenModule.cpp (+1-1)
- (added) clang/test/CodeGenCXX/nocomdat-local-symbol.cpp (+38)
``diff
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp
b/clang/lib/CodeGen/CodeGenModule.cpp
index 05879cd486a8c9..82002b8d8e4d4f 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -3765,7 +3765,7 @@ ConstantAddress
CodeGenModule::GetAddrOfTemplateParamObject(
auto *GV = new llvm::GlobalVariable(getModule(), Init->getType(),
/*isConstant=*/true, Linkage, Init,
Name);
setGVProperties(GV, TPO);
- if (supportsCOMDAT())
+ if (supportsCOMDAT() && Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
Emitter.finalize(GV);
diff --git a/clang/test/CodeGenCXX/nocomdat-local-symbol.cpp
b/clang/test/CodeGenCXX/nocomdat-local-symbol.cpp
new file mode 100644
index 00..3beb7d2197dd59
--- /dev/null
+++ b/clang/test/CodeGenCXX/nocomdat-local-symbol.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -emit-llvm -std=c++20 -triple x86_64-unknown-linux-gnu %s
-o - | FileCheck %s
+
+// COMDAT groups in ELF objects are not permitted to contain local symbols.
While template parameter
+// objects are normally emitted in COMDATs, we shouldn't do so if they would
have internal linkage.
+
+extern "C" int printf(...);
+typedef __typeof__(sizeof(0)) size_t;
+
+namespace {
+template
+struct DebugContext
+{
+char value[N];
+constexpr DebugContext(const char (&str)[N]) {
+for (size_t i = 0; i < N; ++i) {
+value[i] = str[i];
+}
+}
+};
+}
+
+template
+struct ConditionalDebug
+{
+public:
+static void log() {
+printf("%s", Context.value);
+}
+};
+
+using Debug = ConditionalDebug<"compartment A">;
+
+void foo() {
+ Debug::log();
+}
+
+// CHECK-NOT:
$_ZTAXtlN12_GLOBAL__N_112DebugContextILm14EEEtlA14_cLc99ELc111ELc109ELc112ELc97ELc114ELc116ELc109ELc101ELc110ELc116ELc32ELc65
= comdat any
+// CHECK:
@_ZTAXtlN12_GLOBAL__N_112DebugContextILm14EEEtlA14_cLc99ELc111ELc109ELc112ELc97ELc114ELc116ELc109ELc101ELc110ELc116ELc32ELc65
= internal constant %"struct.(anonymous namespace)::DebugContext" { [14 x i8]
c"compartment A\00" }
\ No newline at end of file
``
https://github.com/llvm/llvm-project/pull/125448
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Do not emit template parameter objects as COMDATs when they have internal linkage. (PR #125448)
https://github.com/resistor created
https://github.com/llvm/llvm-project/pull/125448
Per the ELF spec, section groups may only contain local symbols if those
symbols are only
referenced from within the section group. [1] In the case of template parameter
objects,
they can be referenced from outside the group when the type of the object was
declared
in an anonymous namespace. In that case, we can't place the object in a COMDAT.
This matches
GCC's linkage behavior on the test input.
[1]: https://www.sco.com/developers/gabi/latest/ch4.sheader.html#section_groups
>From 7aa7a526bc6876cfe9b3c68e09e3e5f84befed03 Mon Sep 17 00:00:00 2001
From: Owen Anderson
Date: Mon, 3 Feb 2025 15:41:20 +1300
Subject: [PATCH] [clang] Do not emit template parameter objects as COMDATs
when they have internal linkage.
Per the ELF spec, section groups may only contain local symbols if those
symbols are only
referenced from within the section group. [1] In the case of template parameter
objects,
they can be referenced from outside the group when the type of the object was
declared
in an anonymous namespace. In that case, we can't place the object in a COMDAT.
This matches
GCC's linkage behavior on the test input.
[1]: https://www.sco.com/developers/gabi/latest/ch4.sheader.html#section_groups
---
clang/lib/CodeGen/CodeGenModule.cpp | 2 +-
.../test/CodeGenCXX/nocomdat-local-symbol.cpp | 38 +++
2 files changed, 39 insertions(+), 1 deletion(-)
create mode 100644 clang/test/CodeGenCXX/nocomdat-local-symbol.cpp
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp
b/clang/lib/CodeGen/CodeGenModule.cpp
index 05879cd486a8c98..82002b8d8e4d4f1 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -3765,7 +3765,7 @@ ConstantAddress
CodeGenModule::GetAddrOfTemplateParamObject(
auto *GV = new llvm::GlobalVariable(getModule(), Init->getType(),
/*isConstant=*/true, Linkage, Init,
Name);
setGVProperties(GV, TPO);
- if (supportsCOMDAT())
+ if (supportsCOMDAT() && Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
Emitter.finalize(GV);
diff --git a/clang/test/CodeGenCXX/nocomdat-local-symbol.cpp
b/clang/test/CodeGenCXX/nocomdat-local-symbol.cpp
new file mode 100644
index 000..3beb7d2197dd597
--- /dev/null
+++ b/clang/test/CodeGenCXX/nocomdat-local-symbol.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -emit-llvm -std=c++20 -triple x86_64-unknown-linux-gnu %s
-o - | FileCheck %s
+
+// COMDAT groups in ELF objects are not permitted to contain local symbols.
While template parameter
+// objects are normally emitted in COMDATs, we shouldn't do so if they would
have internal linkage.
+
+extern "C" int printf(...);
+typedef __typeof__(sizeof(0)) size_t;
+
+namespace {
+template
+struct DebugContext
+{
+char value[N];
+constexpr DebugContext(const char (&str)[N]) {
+for (size_t i = 0; i < N; ++i) {
+value[i] = str[i];
+}
+}
+};
+}
+
+template
+struct ConditionalDebug
+{
+public:
+static void log() {
+printf("%s", Context.value);
+}
+};
+
+using Debug = ConditionalDebug<"compartment A">;
+
+void foo() {
+ Debug::log();
+}
+
+// CHECK-NOT:
$_ZTAXtlN12_GLOBAL__N_112DebugContextILm14EEEtlA14_cLc99ELc111ELc109ELc112ELc97ELc114ELc116ELc109ELc101ELc110ELc116ELc32ELc65
= comdat any
+// CHECK:
@_ZTAXtlN12_GLOBAL__N_112DebugContextILm14EEEtlA14_cLc99ELc111ELc109ELc112ELc97ELc114ELc116ELc109ELc101ELc110ELc116ELc32ELc65
= internal constant %"struct.(anonymous namespace)::DebugContext" { [14 x i8]
c"compartment A\00" }
\ No newline at end of file
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
