mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 14:59:39 +02:00
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>
This commit is contained in:
@@ -4028,6 +4028,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))
|
||||
@@ -4087,7 +4088,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))
|
||||
|
||||
@@ -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;
|
||||
@@ -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();
|
||||
12
gcc/testsuite/g++.dg/modules/tls-2_a.C
Normal file
12
gcc/testsuite/g++.dg/modules/tls-2_a.C
Normal file
@@ -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;
|
||||
};
|
||||
5
gcc/testsuite/g++.dg/modules/tls-2_b.C
Normal file
5
gcc/testsuite/g++.dg/modules/tls-2_b.C
Normal file
@@ -0,0 +1,5 @@
|
||||
// PR c++/120363
|
||||
// { dg-additional-options "-fmodules" }
|
||||
|
||||
module M;
|
||||
thread_local int test::instance;
|
||||
11
gcc/testsuite/g++.dg/modules/tls-2_c.C
Normal file
11
gcc/testsuite/g++.dg/modules/tls-2_c.C
Normal file
@@ -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();
|
||||
}
|
||||
42
gcc/testsuite/g++.dg/modules/tls-3.h
Normal file
42
gcc/testsuite/g++.dg/modules/tls-3.h
Normal file
@@ -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>();
|
||||
4
gcc/testsuite/g++.dg/modules/tls-3_a.H
Normal file
4
gcc/testsuite/g++.dg/modules/tls-3_a.H
Normal file
@@ -0,0 +1,4 @@
|
||||
// { dg-additional-options "-fmodule-header" }
|
||||
// { dg-module-cmi {} }
|
||||
|
||||
#include "tls-3.h"
|
||||
4
gcc/testsuite/g++.dg/modules/tls-3_b.C
Normal file
4
gcc/testsuite/g++.dg/modules/tls-3_b.C
Normal file
@@ -0,0 +1,4 @@
|
||||
// { dg-additional-options "-fmodules -fno-module-lazy" }
|
||||
|
||||
#include "tls-3.h"
|
||||
import "tls-3_a.H";
|
||||
Reference in New Issue
Block a user