From a8f62a9b32668ea77da721cdc8b9403e507637af Mon Sep 17 00:00:00 2001 From: Nathaniel Shead Date: Thu, 22 May 2025 22:16:22 +1000 Subject: 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 Reviewed-by: Jason Merrill (cherry picked from commit 66e9a4f3083356b064cc64651edad466a56f762b) --- gcc/cp/decl2.cc | 3 ++- gcc/testsuite/g++.dg/modules/pr113292_a.H | 34 ------------------------- gcc/testsuite/g++.dg/modules/pr113292_b.C | 13 ---------- gcc/testsuite/g++.dg/modules/pr113292_c.C | 13 ---------- gcc/testsuite/g++.dg/modules/tls-1_a.H | 34 +++++++++++++++++++++++++ gcc/testsuite/g++.dg/modules/tls-1_b.C | 13 ++++++++++ gcc/testsuite/g++.dg/modules/tls-1_c.C | 13 ++++++++++ gcc/testsuite/g++.dg/modules/tls-2_a.C | 12 +++++++++ gcc/testsuite/g++.dg/modules/tls-2_b.C | 5 ++++ gcc/testsuite/g++.dg/modules/tls-2_c.C | 11 ++++++++ gcc/testsuite/g++.dg/modules/tls-3.h | 42 +++++++++++++++++++++++++++++++ gcc/testsuite/g++.dg/modules/tls-3_a.H | 4 +++ gcc/testsuite/g++.dg/modules/tls-3_b.C | 4 +++ 13 files changed, 140 insertions(+), 61 deletions(-) delete mode 100644 gcc/testsuite/g++.dg/modules/pr113292_a.H delete mode 100644 gcc/testsuite/g++.dg/modules/pr113292_b.C delete mode 100644 gcc/testsuite/g++.dg/modules/pr113292_c.C create mode 100644 gcc/testsuite/g++.dg/modules/tls-1_a.H create mode 100644 gcc/testsuite/g++.dg/modules/tls-1_b.C create mode 100644 gcc/testsuite/g++.dg/modules/tls-1_c.C create mode 100644 gcc/testsuite/g++.dg/modules/tls-2_a.C create mode 100644 gcc/testsuite/g++.dg/modules/tls-2_b.C create mode 100644 gcc/testsuite/g++.dg/modules/tls-2_c.C create mode 100644 gcc/testsuite/g++.dg/modules/tls-3.h create mode 100644 gcc/testsuite/g++.dg/modules/tls-3_a.H create mode 100644 gcc/testsuite/g++.dg/modules/tls-3_b.C (limited to 'gcc') 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/pr113292_a.H deleted file mode 100644 index 90ece2e..0000000 --- a/gcc/testsuite/g++.dg/modules/pr113292_a.H +++ /dev/null @@ -1,34 +0,0 @@ -// PR c++/113292 -// { dg-additional-options "-fmodule-header" } -// { dg-module-cmi {} } - -struct test { - static const test& get_instance() { - return instance; - } - static thread_local test instance; -}; - - -template -struct test_template { - static const test_template& get_instance() { - return instance; - } - static thread_local test_template instance; - - template - static const test_template& get_template_instance() { - return template_instance; - } - - template - static thread_local test_template template_instance; -}; - -template -thread_local test_template test_template::instance; - -template -template -thread_local test_template test_template::template_instance; diff --git a/gcc/testsuite/g++.dg/modules/pr113292_b.C b/gcc/testsuite/g++.dg/modules/pr113292_b.C deleted file mode 100644 index fc582a5..0000000 --- a/gcc/testsuite/g++.dg/modules/pr113292_b.C +++ /dev/null @@ -1,13 +0,0 @@ -// PR c++/113292 -// { dg-additional-options "-fmodules-ts" } - -import "pr113292_a.H"; - -// provide a definition of 'instance' so things link -thread_local test test::instance; - -void instantiate() { - auto& instance = test::get_instance(); - auto& t_instance = test_template::get_instance(); - auto& tt_instance = test_template::get_template_instance(); -}; diff --git a/gcc/testsuite/g++.dg/modules/pr113292_c.C b/gcc/testsuite/g++.dg/modules/pr113292_c.C deleted file mode 100644 index b5acf79..0000000 --- a/gcc/testsuite/g++.dg/modules/pr113292_c.C +++ /dev/null @@ -1,13 +0,0 @@ -// PR c++/113292 -// { dg-module-do link } -// { dg-require-effective-target tls_runtime } -// { dg-add-options tls } -// { dg-additional-options "-fmodules-ts" } - -import "pr113292_a.H"; - -int main() { - auto& instance = test::get_instance(); - auto& t_instance = test_template::get_instance(); - auto& tt_instance = test_template::get_template_instance(); -} diff --git a/gcc/testsuite/g++.dg/modules/tls-1_a.H b/gcc/testsuite/g++.dg/modules/tls-1_a.H new file mode 100644 index 0000000..90ece2e --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/tls-1_a.H @@ -0,0 +1,34 @@ +// PR c++/113292 +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +struct test { + static const test& get_instance() { + return instance; + } + static thread_local test instance; +}; + + +template +struct test_template { + static const test_template& get_instance() { + return instance; + } + static thread_local test_template instance; + + template + static const test_template& get_template_instance() { + return template_instance; + } + + template + static thread_local test_template template_instance; +}; + +template +thread_local test_template test_template::instance; + +template +template +thread_local test_template test_template::template_instance; diff --git a/gcc/testsuite/g++.dg/modules/tls-1_b.C b/gcc/testsuite/g++.dg/modules/tls-1_b.C new file mode 100644 index 0000000..941bff2 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/tls-1_b.C @@ -0,0 +1,13 @@ +// PR c++/113292 +// { dg-additional-options "-fmodules-ts" } + +import "tls-1_a.H"; + +// provide a definition of 'instance' so things link +thread_local test test::instance; + +void instantiate() { + auto& instance = test::get_instance(); + auto& t_instance = test_template::get_instance(); + auto& tt_instance = test_template::get_template_instance(); +}; diff --git a/gcc/testsuite/g++.dg/modules/tls-1_c.C b/gcc/testsuite/g++.dg/modules/tls-1_c.C new file mode 100644 index 0000000..4568413 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/tls-1_c.C @@ -0,0 +1,13 @@ +// PR c++/113292 +// { dg-module-do link } +// { dg-require-effective-target tls_runtime } +// { dg-add-options tls } +// { dg-additional-options "-fmodules-ts" } + +import "tls-1_a.H"; + +int main() { + auto& instance = test::get_instance(); + auto& t_instance = test_template::get_instance(); + auto& tt_instance = test_template::get_template_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 +struct test_template { + static const test_template& get_instance() { + return instance; + } + static thread_local test_template instance; + + template + static const test_template& get_template_instance() { + return template_instance; + } + + template + static thread_local test_template template_instance; +}; + +template +thread_local test_template test_template::instance; + +template +template +thread_local test_template test_template::template_instance; + +template struct test_template; +template const test_template& test_template::get_template_instance(); 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"; -- cgit v1.1