aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathaniel Shead <nathanieloshead@gmail.com>2025-05-22 22:16:22 +1000
committerNathaniel Shead <nathanieloshead@gmail.com>2025-05-24 08:57:40 +1000
commita8f62a9b32668ea77da721cdc8b9403e507637af (patch)
tree7cafe92099d0581220a7d4eccdb6aa7ce9f8e885
parent2486d94bc45a9815395a36cc6dc1e9e3219a74b7 (diff)
downloadgcc-a8f62a9b32668ea77da721cdc8b9403e507637af.zip
gcc-a8f62a9b32668ea77da721cdc8b9403e507637af.tar.gz
gcc-a8f62a9b32668ea77da721cdc8b9403e507637af.tar.bz2
c++/modules: Fix merge of TLS init functions [PR120363]
The PR notes that we missed setting DECL_CONTEXT on the TLS init function; we missed this initially because this function is not created in header units, only named modules. I also noticed that 'DECL_CONTEXT (fn) = DECL_CONTEXT (var)' was incorrect: for class members, this ends up having the modules merging machinery treat the decl as a member function, which breaks when attempting to dedup against an existing completed class type. Instead we can just use the global_namespace as the context, because the name of the function is already mangled appropriately so that we'll match the correct duplicates. PR c++/120363 gcc/cp/ChangeLog: * decl2.cc (get_tls_init_fn): Set context as global_namespace. (get_tls_wrapper_fn): Likewise. gcc/testsuite/ChangeLog: * g++.dg/modules/pr113292_a.H: Move to... * g++.dg/modules/tls-1_a.H: ...here. * g++.dg/modules/pr113292_b.C: Move to... * g++.dg/modules/tls-1_b.C: ...here. * g++.dg/modules/pr113292_c.C: Move to... * g++.dg/modules/tls-1_c.C: ...here. * g++.dg/modules/tls-2_a.C: New test. * g++.dg/modules/tls-2_b.C: New test. * g++.dg/modules/tls-2_c.C: New test. * g++.dg/modules/tls-3.h: New test. * g++.dg/modules/tls-3_a.H: New test. * g++.dg/modules/tls-3_b.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> Reviewed-by: Jason Merrill <jason@redhat.com> (cherry picked from commit 66e9a4f3083356b064cc64651edad466a56f762b)
-rw-r--r--gcc/cp/decl2.cc3
-rw-r--r--gcc/testsuite/g++.dg/modules/tls-1_a.H (renamed from gcc/testsuite/g++.dg/modules/pr113292_a.H)0
-rw-r--r--gcc/testsuite/g++.dg/modules/tls-1_b.C (renamed from gcc/testsuite/g++.dg/modules/pr113292_b.C)2
-rw-r--r--gcc/testsuite/g++.dg/modules/tls-1_c.C (renamed from gcc/testsuite/g++.dg/modules/pr113292_c.C)2
-rw-r--r--gcc/testsuite/g++.dg/modules/tls-2_a.C12
-rw-r--r--gcc/testsuite/g++.dg/modules/tls-2_b.C5
-rw-r--r--gcc/testsuite/g++.dg/modules/tls-2_c.C11
-rw-r--r--gcc/testsuite/g++.dg/modules/tls-3.h42
-rw-r--r--gcc/testsuite/g++.dg/modules/tls-3_a.H4
-rw-r--r--gcc/testsuite/g++.dg/modules/tls-3_b.C4
10 files changed, 82 insertions, 3 deletions
diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index a137e88..bceaf78 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -4026,6 +4026,7 @@ get_tls_init_fn (tree var)
SET_DECL_LANGUAGE (fn, lang_c);
TREE_PUBLIC (fn) = TREE_PUBLIC (var);
DECL_ARTIFICIAL (fn) = true;
+ DECL_CONTEXT (fn) = FROB_CONTEXT (global_namespace);
DECL_COMDAT (fn) = DECL_COMDAT (var);
DECL_EXTERNAL (fn) = DECL_EXTERNAL (var);
if (DECL_ONE_ONLY (var))
@@ -4085,7 +4086,7 @@ get_tls_wrapper_fn (tree var)
TREE_PUBLIC (fn) = TREE_PUBLIC (var);
DECL_ARTIFICIAL (fn) = true;
DECL_IGNORED_P (fn) = 1;
- DECL_CONTEXT (fn) = DECL_CONTEXT (var);
+ DECL_CONTEXT (fn) = FROB_CONTEXT (global_namespace);
/* The wrapper is inline and emitted everywhere var is used. */
DECL_DECLARED_INLINE_P (fn) = true;
if (TREE_PUBLIC (var))
diff --git a/gcc/testsuite/g++.dg/modules/pr113292_a.H b/gcc/testsuite/g++.dg/modules/tls-1_a.H
index 90ece2e..90ece2e 100644
--- a/gcc/testsuite/g++.dg/modules/pr113292_a.H
+++ b/gcc/testsuite/g++.dg/modules/tls-1_a.H
diff --git a/gcc/testsuite/g++.dg/modules/pr113292_b.C b/gcc/testsuite/g++.dg/modules/tls-1_b.C
index fc582a5..941bff2 100644
--- a/gcc/testsuite/g++.dg/modules/pr113292_b.C
+++ b/gcc/testsuite/g++.dg/modules/tls-1_b.C
@@ -1,7 +1,7 @@
// PR c++/113292
// { dg-additional-options "-fmodules-ts" }
-import "pr113292_a.H";
+import "tls-1_a.H";
// provide a definition of 'instance' so things link
thread_local test test::instance;
diff --git a/gcc/testsuite/g++.dg/modules/pr113292_c.C b/gcc/testsuite/g++.dg/modules/tls-1_c.C
index b5acf79..4568413 100644
--- a/gcc/testsuite/g++.dg/modules/pr113292_c.C
+++ b/gcc/testsuite/g++.dg/modules/tls-1_c.C
@@ -4,7 +4,7 @@
// { dg-add-options tls }
// { dg-additional-options "-fmodules-ts" }
-import "pr113292_a.H";
+import "tls-1_a.H";
int main() {
auto& instance = test::get_instance();
diff --git a/gcc/testsuite/g++.dg/modules/tls-2_a.C b/gcc/testsuite/g++.dg/modules/tls-2_a.C
new file mode 100644
index 0000000..2efae6c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/tls-2_a.C
@@ -0,0 +1,12 @@
+// PR c++/120363
+// { dg-additional-options "-fmodules" }
+// { dg-module-cmi M }
+
+export module M;
+
+export struct test {
+ static inline const int& get_instance() {
+ return instance;
+ }
+ static thread_local int instance;
+};
diff --git a/gcc/testsuite/g++.dg/modules/tls-2_b.C b/gcc/testsuite/g++.dg/modules/tls-2_b.C
new file mode 100644
index 0000000..af3e709
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/tls-2_b.C
@@ -0,0 +1,5 @@
+// PR c++/120363
+// { dg-additional-options "-fmodules" }
+
+module M;
+thread_local int test::instance;
diff --git a/gcc/testsuite/g++.dg/modules/tls-2_c.C b/gcc/testsuite/g++.dg/modules/tls-2_c.C
new file mode 100644
index 0000000..4489516
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/tls-2_c.C
@@ -0,0 +1,11 @@
+// PR c++/120363
+// { dg-module-do link }
+// { dg-require-effective-target tls_runtime }
+// { dg-add-options tls }
+// { dg-additional-options "-fmodules" }
+
+import M;
+
+int main() {
+ auto& instance = test::get_instance();
+}
diff --git a/gcc/testsuite/g++.dg/modules/tls-3.h b/gcc/testsuite/g++.dg/modules/tls-3.h
new file mode 100644
index 0000000..6f4a236
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/tls-3.h
@@ -0,0 +1,42 @@
+inline thread_local int tla;
+inline int& get_tla() {
+ return tla;
+}
+
+static thread_local int tlb;
+static int& get_tlb() {
+ return tlb;
+}
+
+struct test {
+ static const test& get_instance() {
+ return instance;
+ }
+ static thread_local test instance;
+};
+
+template <typename T>
+struct test_template {
+ static const test_template& get_instance() {
+ return instance;
+ }
+ static thread_local test_template instance;
+
+ template <typename U>
+ static const test_template& get_template_instance() {
+ return template_instance<U>;
+ }
+
+ template <typename U>
+ static thread_local test_template template_instance;
+};
+
+template <typename T>
+thread_local test_template<T> test_template<T>::instance;
+
+template <typename T>
+template <typename U>
+thread_local test_template<T> test_template<T>::template_instance;
+
+template struct test_template<int>;
+template const test_template<int>& test_template<int>::get_template_instance<int>();
diff --git a/gcc/testsuite/g++.dg/modules/tls-3_a.H b/gcc/testsuite/g++.dg/modules/tls-3_a.H
new file mode 100644
index 0000000..beef907
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/tls-3_a.H
@@ -0,0 +1,4 @@
+// { dg-additional-options "-fmodule-header" }
+// { dg-module-cmi {} }
+
+#include "tls-3.h"
diff --git a/gcc/testsuite/g++.dg/modules/tls-3_b.C b/gcc/testsuite/g++.dg/modules/tls-3_b.C
new file mode 100644
index 0000000..ab77b1e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/tls-3_b.C
@@ -0,0 +1,4 @@
+// { dg-additional-options "-fmodules -fno-module-lazy" }
+
+#include "tls-3.h"
+import "tls-3_a.H";