]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR c++/60702 (thread_local initialization)
authorJakub Jelinek <jakub@redhat.com>
Fri, 30 Aug 2019 12:30:48 +0000 (14:30 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 30 Aug 2019 12:30:48 +0000 (14:30 +0200)
Backported from mainline
2019-03-22  Jakub Jelinek  <jakub@redhat.com>

PR c++/60702
* cp-tree.h (get_tls_wrapper_fn): Remove declaration.
(maybe_get_tls_wrapper_call): Declare.
* decl2.c (get_tls_wrapper_fn): Make static.
(maybe_get_tls_wrapper_call): New function.
* typeck.c (build_class_member_access_expr): Handle accesses to TLS
variables.
* semantics.c (finish_qualified_id_expr): Likewise.
(finish_id_expression_1): Use maybe_get_tls_wrapper_call.
* pt.c (tsubst_copy_and_build): Likewise.

* g++.dg/tls/thread_local11.C: New test.
* g++.dg/tls/thread_local11.h: New test.
* g++.dg/tls/thread_local12a.C: New test.
* g++.dg/tls/thread_local12b.C: New test.
* g++.dg/tls/thread_local12c.C: New test.
* g++.dg/tls/thread_local12d.C: New test.
* g++.dg/tls/thread_local12e.C: New test.
* g++.dg/tls/thread_local12f.C: New test.
* g++.dg/tls/thread_local12g.C: New test.
* g++.dg/tls/thread_local12h.C: New test.
* g++.dg/tls/thread_local12i.C: New test.
* g++.dg/tls/thread_local12j.C: New test.
* g++.dg/tls/thread_local12k.C: New test.
* g++.dg/tls/thread_local12l.C: New test.

From-SVN: r275140

21 files changed:
gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl2.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/tls/thread_local11.C [new file with mode: 0644]
gcc/testsuite/g++.dg/tls/thread_local11.h [new file with mode: 0644]
gcc/testsuite/g++.dg/tls/thread_local12a.C [new file with mode: 0644]
gcc/testsuite/g++.dg/tls/thread_local12b.C [new file with mode: 0644]
gcc/testsuite/g++.dg/tls/thread_local12c.C [new file with mode: 0644]
gcc/testsuite/g++.dg/tls/thread_local12d.C [new file with mode: 0644]
gcc/testsuite/g++.dg/tls/thread_local12e.C [new file with mode: 0644]
gcc/testsuite/g++.dg/tls/thread_local12f.C [new file with mode: 0644]
gcc/testsuite/g++.dg/tls/thread_local12g.C [new file with mode: 0644]
gcc/testsuite/g++.dg/tls/thread_local12h.C [new file with mode: 0644]
gcc/testsuite/g++.dg/tls/thread_local12i.C [new file with mode: 0644]
gcc/testsuite/g++.dg/tls/thread_local12j.C [new file with mode: 0644]
gcc/testsuite/g++.dg/tls/thread_local12k.C [new file with mode: 0644]
gcc/testsuite/g++.dg/tls/thread_local12l.C [new file with mode: 0644]

index 5d7aaa65eb0a79cb17ee2fe783ea35689148abcd..14beaa8c0cf7154d4ccb5e27e6bdb30b602da308 100644 (file)
@@ -1,6 +1,19 @@
 2019-08-30  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2019-03-22  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/60702
+       * cp-tree.h (get_tls_wrapper_fn): Remove declaration.
+       (maybe_get_tls_wrapper_call): Declare.
+       * decl2.c (get_tls_wrapper_fn): Make static.
+       (maybe_get_tls_wrapper_call): New function.
+       * typeck.c (build_class_member_access_expr): Handle accesses to TLS
+       variables.
+       * semantics.c (finish_qualified_id_expr): Likewise.
+       (finish_id_expression_1): Use maybe_get_tls_wrapper_call.
+       * pt.c (tsubst_copy_and_build): Likewise.
+
        2019-03-21  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/89767
index 842d410f8421914c286ab129e3d687ba567d2015..7e31f90916746373449485f943d0831b0378b98f 100644 (file)
@@ -5962,7 +5962,7 @@ extern tree cp_build_parm_decl                    (tree, tree);
 extern tree get_guard                          (tree);
 extern tree get_guard_cond                     (tree, bool);
 extern tree set_guard                          (tree);
-extern tree get_tls_wrapper_fn                 (tree);
+extern tree maybe_get_tls_wrapper_call         (tree);
 extern void mark_needed                                (tree);
 extern bool decl_needed_p                      (tree);
 extern void note_vague_linkage_fn              (tree);
index 7839e6246008377ce3f6019bb438ae58665051cc..77ca73a8d5e20cbe201ec11227df5c2a199fb86d 100644 (file)
@@ -3255,7 +3255,7 @@ get_tls_init_fn (tree var)
    VAR and then returns a reference to VAR.  The wrapper function is used
    in place of VAR everywhere VAR is mentioned.  */
 
-tree
+static tree
 get_tls_wrapper_fn (tree var)
 {
   /* Only C++11 TLS vars need this wrapper fn.  */
@@ -3307,6 +3307,22 @@ get_tls_wrapper_fn (tree var)
   return fn;
 }
 
+/* If EXPR is a thread_local variable that should be wrapped by init
+   wrapper function, return a call to that function, otherwise return
+   NULL.  */
+
+tree
+maybe_get_tls_wrapper_call (tree expr)
+{
+  if (VAR_P (expr)
+      && !processing_template_decl
+      && !cp_unevaluated_operand
+      && CP_DECL_THREAD_LOCAL_P (expr))
+    if (tree wrap = get_tls_wrapper_fn (expr))
+      return build_cxx_call (wrap, 0, NULL, tf_warning_or_error);
+  return NULL;
+}
+
 /* At EOF, generate the definition for the TLS wrapper function FN:
 
    T& var_wrapper() {
index 2df7402c905bb55e84a6c05dd79fc8227d3cef89..c85594e90db26e74c6ca7ddff581a04f7498574c 100644 (file)
@@ -17897,17 +17897,10 @@ tsubst_copy_and_build (tree t,
       {
        tree r = tsubst_copy (t, args, complain, in_decl);
        /* ??? We're doing a subset of finish_id_expression here.  */
-       if (VAR_P (r)
-           && !processing_template_decl
-           && !cp_unevaluated_operand
-           && (TREE_STATIC (r) || DECL_EXTERNAL (r))
-           && CP_DECL_THREAD_LOCAL_P (r))
-         {
-           if (tree wrap = get_tls_wrapper_fn (r))
-             /* Replace an evaluated use of the thread_local variable with
-                a call to its wrapper.  */
-             r = build_cxx_call (wrap, 0, NULL, tf_warning_or_error);
-         }
+       if (tree wrap = maybe_get_tls_wrapper_call (r))
+         /* Replace an evaluated use of the thread_local variable with
+            a call to its wrapper.  */
+         r = wrap;
        else if (outer_automatic_var_p (r))
          {
            r = process_outer_var_ref (r, complain);
index d0d0658c81fe689732cebc11ba1ce275e044d3d6..342857a0cb1547ef808fca28183676d8747db1a4 100644 (file)
@@ -2087,6 +2087,8 @@ finish_qualified_id_expr (tree qualifying_class,
        expr = build_qualified_name (TREE_TYPE (expr),
                                     qualifying_class, expr,
                                     template_p);
+      else if (tree wrap = maybe_get_tls_wrapper_call (expr))
+       expr = wrap;
 
       expr = convert_from_reference (expr);
     }
@@ -3746,18 +3748,10 @@ finish_id_expression (tree id_expression,
          *non_integral_constant_expression_p = true;
        }
 
-      tree wrap;
-      if (VAR_P (decl)
-         && !cp_unevaluated_operand
-         && !processing_template_decl
-         && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
-         && CP_DECL_THREAD_LOCAL_P (decl)
-         && (wrap = get_tls_wrapper_fn (decl)))
-       {
-         /* Replace an evaluated use of the thread_local variable with
-            a call to its wrapper.  */
-         decl = build_cxx_call (wrap, 0, NULL, tf_warning_or_error);
-       }
+      if (tree wrap = maybe_get_tls_wrapper_call (decl))
+       /* Replace an evaluated use of the thread_local variable with
+          a call to its wrapper.  */
+       decl = wrap;
       else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
               && variable_template_p (TREE_OPERAND (decl, 0)))
        {
index 3b30a1e5b195862f1a26966edc03e71f49473f48..305444b2d93f03e1dff6519e29fed6aea734002e 100644 (file)
@@ -2378,6 +2378,12 @@ build_class_member_access_expr (cp_expr object, tree member,
       /* A static data member.  */
       result = member;
       mark_exp_read (object);
+
+      if (tree wrap = maybe_get_tls_wrapper_call (result))
+       /* Replace an evaluated use of the thread_local variable with
+          a call to its wrapper.  */
+       result = wrap;
+
       /* If OBJECT has side-effects, they are supposed to occur.  */
       if (TREE_SIDE_EFFECTS (object))
        result = build2 (COMPOUND_EXPR, TREE_TYPE (result), object, result);
index 21817bba375b4580348180f52863c14d0e6c4d12..f4cd0d17850399ff773cc8bd883d06bcfa44fc9e 100644 (file)
@@ -1,6 +1,24 @@
 2019-08-30  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2019-03-22  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/60702
+       * g++.dg/tls/thread_local11.C: New test.
+       * g++.dg/tls/thread_local11.h: New test.
+       * g++.dg/tls/thread_local12a.C: New test.
+       * g++.dg/tls/thread_local12b.C: New test.
+       * g++.dg/tls/thread_local12c.C: New test.
+       * g++.dg/tls/thread_local12d.C: New test.
+       * g++.dg/tls/thread_local12e.C: New test.
+       * g++.dg/tls/thread_local12f.C: New test.
+       * g++.dg/tls/thread_local12g.C: New test.
+       * g++.dg/tls/thread_local12h.C: New test.
+       * g++.dg/tls/thread_local12i.C: New test.
+       * g++.dg/tls/thread_local12j.C: New test.
+       * g++.dg/tls/thread_local12k.C: New test.
+       * g++.dg/tls/thread_local12l.C: New test.
+
        2019-03-21  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/89767
diff --git a/gcc/testsuite/g++.dg/tls/thread_local11.C b/gcc/testsuite/g++.dg/tls/thread_local11.C
new file mode 100644 (file)
index 0000000..036d91a
--- /dev/null
@@ -0,0 +1,48 @@
+// PR c++/60702
+// { dg-do compile { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+// { dg-additional-options "-fdump-tree-gimple" }
+// { dg-final { scan-tree-dump-times "_ZTW2s1" 2 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTW2s2" 2 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTW2s3" 2 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTW2s4" 2 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTWN1T2u1E" 2 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTWN1T2u2E" 2 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTWN1T2u3E" 2 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTWN1T2u4E" 2 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTWN1T2u5E" 2 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTWN1T2u6E" 2 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTWN1T2u7E" 2 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTWN1T2u8E" 2 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTH2s1" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTH2s2" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTH2s3" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTH2s4" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u1E" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u2E" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u3E" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u4E" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u5E" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u6E" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u7E" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u8E" 1 "gimple" } }
+
+#include "thread_local11.h"
+
+void
+foo ()
+{
+  f1 ();
+  f2 ();
+  f3 ();
+  f4 ();
+  f5 ();
+  f6 ();
+  f7<0> ();
+  f8<0> ();
+  f9<0> ();
+  f10<0> ();
+  f11<0> ();
+  f12<0> ();
+}
diff --git a/gcc/testsuite/g++.dg/tls/thread_local11.h b/gcc/testsuite/g++.dg/tls/thread_local11.h
new file mode 100644 (file)
index 0000000..761b42d
--- /dev/null
@@ -0,0 +1,26 @@
+// PR c++/60702
+
+extern "C" void abort ();
+struct S { S () { i = 42; }; int i; };
+thread_local S s1, s2, s3, s4;
+struct T { static thread_local S u1, u2, u3, u4, u5, u6, u7, u8; int i; } t;
+thread_local S T::u1, T::u2, T::u3, T::u4, T::u5, T::u6, T::u7, T::u8;
+
+S *f1 () { return &s1; }
+int *f2 () { return &s2.i; }
+S *f3 () { return &t.u1; }
+int *f4 () { return &t.u2.i; }
+S *f5 () { return &T::u3; }
+int *f6 () { return &T::u4.i; }
+template <int N>
+S *f7 () { return &s3; }
+template <int N>
+int *f8 () { return &s4.i; }
+template <int N>
+S *f9 () { return &t.u5; }
+template <int N>
+int *f10 () { return &t.u6.i; }
+template <int N>
+S *f11 () { return &T::u7; }
+template <int N>
+int *f12 () { return &T::u8.i; }
diff --git a/gcc/testsuite/g++.dg/tls/thread_local12a.C b/gcc/testsuite/g++.dg/tls/thread_local12a.C
new file mode 100644 (file)
index 0000000..87a1716
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/60702
+// { dg-do run { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+
+#include "thread_local11.h"
+
+int
+main ()
+{
+  if (f1 ()->i != 42) abort ();
+}
diff --git a/gcc/testsuite/g++.dg/tls/thread_local12b.C b/gcc/testsuite/g++.dg/tls/thread_local12b.C
new file mode 100644 (file)
index 0000000..498bace
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/60702
+// { dg-do run { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+
+#include "thread_local11.h"
+
+int
+main ()
+{
+  if (*f2 () != 42) abort ();
+}
diff --git a/gcc/testsuite/g++.dg/tls/thread_local12c.C b/gcc/testsuite/g++.dg/tls/thread_local12c.C
new file mode 100644 (file)
index 0000000..92add8f
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/60702
+// { dg-do run { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+
+#include "thread_local11.h"
+
+int
+main ()
+{
+  if (f3 ()->i != 42) abort ();
+}
diff --git a/gcc/testsuite/g++.dg/tls/thread_local12d.C b/gcc/testsuite/g++.dg/tls/thread_local12d.C
new file mode 100644 (file)
index 0000000..7863136
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/60702
+// { dg-do run { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+
+#include "thread_local11.h"
+
+int
+main ()
+{
+  if (*f4 () != 42) abort ();
+}
diff --git a/gcc/testsuite/g++.dg/tls/thread_local12e.C b/gcc/testsuite/g++.dg/tls/thread_local12e.C
new file mode 100644 (file)
index 0000000..95c44f7
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/60702
+// { dg-do run { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+
+#include "thread_local11.h"
+
+int
+main ()
+{
+  if (f5 ()->i != 42) abort ();
+}
diff --git a/gcc/testsuite/g++.dg/tls/thread_local12f.C b/gcc/testsuite/g++.dg/tls/thread_local12f.C
new file mode 100644 (file)
index 0000000..e7795dc
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/60702
+// { dg-do run { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+
+#include "thread_local11.h"
+
+int
+main ()
+{
+  if (*f6 () != 42) abort ();
+}
diff --git a/gcc/testsuite/g++.dg/tls/thread_local12g.C b/gcc/testsuite/g++.dg/tls/thread_local12g.C
new file mode 100644 (file)
index 0000000..c7c964a
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/60702
+// { dg-do run { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+
+#include "thread_local11.h"
+
+int
+main ()
+{
+  if (f7<0> ()->i != 42) abort ();
+}
diff --git a/gcc/testsuite/g++.dg/tls/thread_local12h.C b/gcc/testsuite/g++.dg/tls/thread_local12h.C
new file mode 100644 (file)
index 0000000..32b6841
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/60702
+// { dg-do run { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+
+#include "thread_local11.h"
+
+int
+main ()
+{
+  if (*f8<0> () != 42) abort ();
+}
diff --git a/gcc/testsuite/g++.dg/tls/thread_local12i.C b/gcc/testsuite/g++.dg/tls/thread_local12i.C
new file mode 100644 (file)
index 0000000..815e14e
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/60702
+// { dg-do run { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+
+#include "thread_local11.h"
+
+int
+main ()
+{
+  if (f9<0> ()->i != 42) abort ();
+}
diff --git a/gcc/testsuite/g++.dg/tls/thread_local12j.C b/gcc/testsuite/g++.dg/tls/thread_local12j.C
new file mode 100644 (file)
index 0000000..0009de1
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/60702
+// { dg-do run { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+
+#include "thread_local11.h"
+
+int
+main ()
+{
+  if (*f10<0> () != 42) abort ();
+}
diff --git a/gcc/testsuite/g++.dg/tls/thread_local12k.C b/gcc/testsuite/g++.dg/tls/thread_local12k.C
new file mode 100644 (file)
index 0000000..589e872
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/60702
+// { dg-do run { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+
+#include "thread_local11.h"
+
+int
+main ()
+{
+  if (f11<0> ()->i != 42) abort ();
+}
diff --git a/gcc/testsuite/g++.dg/tls/thread_local12l.C b/gcc/testsuite/g++.dg/tls/thread_local12l.C
new file mode 100644 (file)
index 0000000..273e1be
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/60702
+// { dg-do run { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+
+#include "thread_local11.h"
+
+int
+main ()
+{
+  if (*f12<0> () != 42) abort ();
+}