diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2025-07-31 07:38:48 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2025-09-07 07:02:58 -0700 |
commit | a0344144dbccccf039f431a368f486f9dc6813ab (patch) | |
tree | e40d1f0b63e5ccec8b4a2c6ea72bc67c2810227c | |
parent | 93af5f69d15934edda4ff6a6eb63bde9ae7b8e45 (diff) | |
download | gcc-a0344144dbccccf039f431a368f486f9dc6813ab.zip gcc-a0344144dbccccf039f431a368f486f9dc6813ab.tar.gz gcc-a0344144dbccccf039f431a368f486f9dc6813ab.tar.bz2 |
c++: Update TLS model after processing a TLS variable
Set a tentative TLS model in grokvardecl and update TLS mode with the
default TLS access model after a TLS variable has been fully processed
if the default TLS access model is stronger.
gcc/cp/
PR c++/107393
* decl.cc (grokvardecl): Set a tentative TLS model which will be
updated by cplus_decl_attributes later.
* decl2.cc (cplus_decl_attributes): Update TLS model with the
default TLS access model if the default TLS access model is
stronger.
* pt.cc (tsubst_decl): Set TLS model only after processing a
variable.
gcc/testsuite/
PR c++/107393
* g++.dg/tls/pr107393-1.C: New test.
* g++.dg/tls/pr107393-2.C: Likewise.
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
-rw-r--r-- | gcc/cp/decl.cc | 5 | ||||
-rw-r--r-- | gcc/cp/decl2.cc | 9 | ||||
-rw-r--r-- | gcc/cp/pt.cc | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tls/pr107393-1.C | 14 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tls/pr107393-2.C | 29 |
5 files changed, 61 insertions, 4 deletions
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index f088d09..a6a9842 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -12183,8 +12183,11 @@ grokvardecl (tree type, if (DECL_EXTERNAL (decl) || TREE_STATIC (decl)) { CP_DECL_THREAD_LOCAL_P (decl) = true; + // NB: Set a tentative TLS model to avoid tls_model attribute + // warnings due to lack of thread storage duration. It will + // be updated by cplus_decl_attributes later. if (!processing_template_decl) - set_decl_tls_model (decl, decl_default_tls_model (decl)); + set_decl_tls_model (decl, TLS_MODEL_REAL); } if (declspecs->gnu_thread_keyword_p) SET_DECL_GNU_TLS_P (decl); diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc index 6499be1..c9cca7b 100644 --- a/gcc/cp/decl2.cc +++ b/gcc/cp/decl2.cc @@ -2013,6 +2013,15 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags) if (*decl == pattern) TREE_UNAVAILABLE (tmpl) = true; } + + if (VAR_P (*decl) && CP_DECL_THREAD_LOCAL_P (*decl)) + { + // tls_model attribute can set a stronger TLS access model. + tls_model model = DECL_TLS_MODEL (*decl); + tls_model default_model = decl_default_tls_model (*decl); + if (default_model > model) + set_decl_tls_model (*decl, default_model); + } } /* Walks through the namespace- or function-scope anonymous union diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 365a6c5..7f0d16f 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -16034,9 +16034,6 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain, == TYPE_MAIN_VARIANT (type)); SET_DECL_VALUE_EXPR (r, ve); } - if (CP_DECL_THREAD_LOCAL_P (r) - && !processing_template_decl) - set_decl_tls_model (r, decl_default_tls_model (r)); } else if (DECL_SELF_REFERENCE_P (t)) SET_DECL_SELF_REFERENCE_P (r); @@ -16099,6 +16096,11 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain, register_local_specialization (r, t); } + if (VAR_P (r) + && CP_DECL_THREAD_LOCAL_P (r) + && !processing_template_decl) + set_decl_tls_model (r, decl_default_tls_model (r)); + DECL_CHAIN (r) = NULL_TREE; if (!apply_late_template_attributes (&r, DECL_ATTRIBUTES (r), diff --git a/gcc/testsuite/g++.dg/tls/pr107393-1.C b/gcc/testsuite/g++.dg/tls/pr107393-1.C new file mode 100644 index 0000000..644b4f4 --- /dev/null +++ b/gcc/testsuite/g++.dg/tls/pr107393-1.C @@ -0,0 +1,14 @@ +// { dg-do compile { target c++11 } } +// { dg-require-effective-target fpic } +// { dg-require-effective-target tls } +// { dg-options "-O2 -fno-pic -fdump-ipa-whole-program" } +// { dg-add-options tls } + +struct Dtor; +template <typename> struct X { static thread_local Dtor m; }; +template <typename T> thread_local Dtor X<T>::m; +extern template Dtor X<char>::m; +void *e2 = &X<char>::m; + +// tls_model should be tls-initial-exec due to extern template. +// { dg-final { scan-ipa-dump "Varpool flags: tls-initial-exec" "whole-program" } } diff --git a/gcc/testsuite/g++.dg/tls/pr107393-2.C b/gcc/testsuite/g++.dg/tls/pr107393-2.C new file mode 100644 index 0000000..6a69800 --- /dev/null +++ b/gcc/testsuite/g++.dg/tls/pr107393-2.C @@ -0,0 +1,29 @@ +// { dg-do compile } +// { dg-require-effective-target fpic } +// { dg-require-effective-target tls } +// { dg-options "-O2 -fno-pic -fdump-ipa-whole-program" } +// { dg-add-options tls } + +template<class T> +struct S { + static __thread int i; +}; + +template<class T> +__thread int S<T>::i; + +extern template +__thread int S<void>::i; + +int &vi() +{ + return S<void>::i; +} + +int &ci() +{ + return S<char>::i; +} + +// tls_model should be tls-initial-exec due to extern template. +// { dg-final { scan-ipa-dump "Varpool flags: tls-initial-exec" "whole-program" } } |