diff options
| author | Nathaniel Shead <nathanieloshead@gmail.com> | 2024-01-11 16:49:39 +1100 |
|---|---|---|
| committer | Nathaniel Shead <nathanieloshead@gmail.com> | 2024-01-17 09:40:42 +1100 |
| commit | 14338386970bc6c2d46b81181f48622fdf25d705 (patch) | |
| tree | 3a3a5e7272a1290aef1a2f540a1d7bbe7393fa4d /gcc/cp/module.cc | |
| parent | fe1649eea76f193732d22ec022a35326523eb37a (diff) | |
| download | gcc-14338386970bc6c2d46b81181f48622fdf25d705.zip gcc-14338386970bc6c2d46b81181f48622fdf25d705.tar.gz gcc-14338386970bc6c2d46b81181f48622fdf25d705.tar.bz2 | |
c++: Support thread_local statics in header modules [PR113292]
Currently, thread_locals in header modules cause ICEs. This patch makes
the required changes for them to work successfully.
This requires additionally writing the DECL_TLS_MODEL for thread-local
variables to the module interface, and the TLS wrapper function needs to
have its DECL_BEFRIENDING_CLASSES written too as this is used to
retrieve what VAR_DECL it's a wrapper for when emitting a definition at
end of TU processing.
PR c++/113292
gcc/cp/ChangeLog:
* decl2.cc (get_tls_wrapper_fn): Set DECL_CONTEXT.
(c_parse_final_cleanups): Suppress warning for no definition of
TLS wrapper functions in header modules.
* module.cc (trees_out::lang_decl_vals): Write wrapped variable
for TLS wrapper functions.
(trees_in::lang_decl_vals): Read it.
(trees_out::decl_value): Write TLS model for thread-local vars.
(trees_in::decl_value): Read it for new decls. Remember to emit
definitions of TLS wrapper functions later.
gcc/testsuite/ChangeLog:
* g++.dg/modules/pr113292_a.H: New test.
* g++.dg/modules/pr113292_b.C: New test.
* g++.dg/modules/pr113292_c.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Diffstat (limited to 'gcc/cp/module.cc')
| -rw-r--r-- | gcc/cp/module.cc | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index aa75e28..350ad15 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -6950,6 +6950,9 @@ trees_out::lang_decl_vals (tree t) if (streaming_p ()) wi (lang->u.fn.u5.fixed_offset); } + else if (decl_tls_wrapper_p (t)) + /* The wrapped variable. */ + WT (lang->u.fn.befriending_classes); else WT (lang->u.fn.u5.cloned_function); @@ -7029,6 +7032,8 @@ trees_in::lang_decl_vals (tree t) RT (lang->u.fn.befriending_classes); lang->u.fn.u5.fixed_offset = wi (); } + else if (decl_tls_wrapper_p (t)) + RT (lang->u.fn.befriending_classes); else RT (lang->u.fn.u5.cloned_function); @@ -7928,6 +7933,9 @@ trees_out::decl_value (tree decl, depset *dep) decl, cloned_p ? "" : "not "); } + if (streaming_p () && VAR_P (decl) && CP_DECL_THREAD_LOCAL_P (decl)) + u (decl_tls_model (decl)); + if (streaming_p ()) dump (dumper::TREE) && dump ("Written decl:%d %C:%N", tag, TREE_CODE (decl), decl); @@ -8275,6 +8283,13 @@ trees_in::decl_value () look like templates. */ if (!install_implicit_member (inner)) set_overrun (); + + /* When importing a TLS wrapper from a header unit, we haven't + actually emitted its definition yet. Remember it so we can + do this later. */ + if (state->is_header () + && decl_tls_wrapper_p (decl)) + note_vague_linkage_fn (decl); } else { @@ -8358,6 +8373,13 @@ trees_in::decl_value () } } + if (VAR_P (decl) && CP_DECL_THREAD_LOCAL_P (decl)) + { + enum tls_model model = tls_model (u ()); + if (is_new) + set_decl_tls_model (decl, model); + } + if (!NAMESPACE_SCOPE_P (inner) && ((TREE_CODE (inner) == TYPE_DECL && !is_typedef |
