]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Fix handling of __thread/thread_local extern vars declared at function scope...
authorJakub Jelinek <jakub@redhat.com>
Fri, 1 Oct 2021 08:30:16 +0000 (10:30 +0200)
committerJakub Jelinek <jakub@redhat.com>
Fri, 1 Oct 2021 08:30:16 +0000 (10:30 +0200)
The introduction of push_local_extern_decl_alias in
r11-3699-g4e62aca0e0520e4ed2532f2d8153581190621c1a
broke tls vars, while the decl they are created for has the tls model
set properly, nothing sets it for the alias that is actually used,
so accesses to it are done as if they were normal variables.
This is then diagnosed at link time if the definition of the extern
vars is __thread/thread_local.

2021-10-01  Jakub Jelinek  <jakub@redhat.com>

PR c++/102496
* name-lookup.c (push_local_extern_decl_alias): Return early even for
tls vars with non-dependent type when processing_template_decl.  For
CP_DECL_THREAD_LOCAL_P vars call set_decl_tls_model on alias.

* g++.dg/tls/pr102496-1.C: New test.
* g++.dg/tls/pr102496-2.C: New test.

gcc/cp/name-lookup.c
gcc/testsuite/g++.dg/tls/pr102496-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/tls/pr102496-2.C [new file with mode: 0644]

index ddee8b390f9debed0f5515bc45e4667b28bb8dd6..c414a1091b449826a91188667dc58932281c715d 100644 (file)
@@ -3375,7 +3375,10 @@ set_decl_context_in_fn (tree ctx, tree decl)
 void
 push_local_extern_decl_alias (tree decl)
 {
-  if (dependent_type_p (TREE_TYPE (decl)))
+  if (dependent_type_p (TREE_TYPE (decl))
+      || (processing_template_decl
+         && VAR_P (decl)
+         && CP_DECL_THREAD_LOCAL_P (decl)))
     return;
   /* EH specs were not part of the function type prior to c++17, but
      we still can't go pushing dependent eh specs into the namespace.  */
@@ -3471,6 +3474,8 @@ push_local_extern_decl_alias (tree decl)
          push_nested_namespace (ns);
          alias = do_pushdecl (alias, /* hiding= */true);
          pop_nested_namespace (ns);
+         if (VAR_P (decl) && CP_DECL_THREAD_LOCAL_P (decl))
+           set_decl_tls_model (alias, DECL_TLS_MODEL (decl));
        }
     }
 
diff --git a/gcc/testsuite/g++.dg/tls/pr102496-1.C b/gcc/testsuite/g++.dg/tls/pr102496-1.C
new file mode 100644 (file)
index 0000000..8220e1e
--- /dev/null
@@ -0,0 +1,20 @@
+// PR c++/102496
+// { dg-do link { target c++11 } }
+// { dg-require-effective-target tls }
+// { dg-add-options tls }
+// { dg-additional-sources pr102496-2.C }
+
+template <int N>
+int
+foo ()
+{
+  extern __thread int t1;
+  return t1;
+}
+
+int
+main ()
+{
+  extern __thread int t2;
+  return foo <0> () + t2;
+}
diff --git a/gcc/testsuite/g++.dg/tls/pr102496-2.C b/gcc/testsuite/g++.dg/tls/pr102496-2.C
new file mode 100644 (file)
index 0000000..a71a9cd
--- /dev/null
@@ -0,0 +1,6 @@
+// PR c++/102496
+// { dg-do compile { target c++11 } }
+// { dg-require-effective-target tls }
+
+__thread int t1;
+__thread int t2;