This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++ PATCH] Fix thread_local initialization (PR c++/60702)


Hi!

As the testcase shows, we replace TLS vars that need initialization
in finish_id_expression_1 and in tsubst_copy_and_build of a VAR_DECL
with a _ZTW* call, but miss it in other cases where finish_id_expression
is not actually called.  In particular build_class_member_access_expr
when we do object.static_tls_data_member access doesn't wrap it, and
when using some_class::static_tls_data_member in a teplate, we go
through finish_qualified_id_expr and not finish_id_expression either
(and tsubst_copy in that case, so it doesn't go through
tsubst_copy_and_build).

The following patch fixes that.  While it is not a regression, it is a
serious wrong-code issue that just gained 6th reporter of the same issue.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2019-03-15  Jakub Jelinek  <jakub@redhat.com>

	PR c++/60702
	* semantics.c (finish_qualified_id_expr): Handle accesses to TLS
	variables.
	* typeck.c (build_class_member_access_expr): 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.

--- gcc/cp/semantics.c.jj	2019-03-14 09:14:16.718012031 +0100
+++ gcc/cp/semantics.c	2019-03-15 16:53:14.270384477 +0100
@@ -2135,6 +2135,17 @@ finish_qualified_id_expr (tree qualifyin
 	expr = build_qualified_name (TREE_TYPE (expr),
 				     qualifying_class, expr,
 				     template_p);
+      else if (VAR_P (expr)
+	       && !processing_template_decl
+	       && !cp_unevaluated_operand
+	       && (TREE_STATIC (expr) || DECL_EXTERNAL (expr))
+	       && CP_DECL_THREAD_LOCAL_P (expr))
+	{
+	  if (tree wrap = get_tls_wrapper_fn (expr))
+	    /* Replace an evaluated use of the thread_local variable with
+	       a call to its wrapper.  */
+	    expr = build_cxx_call (wrap, 0, NULL, tf_warning_or_error);
+	}
 
       expr = convert_from_reference (expr);
     }
--- gcc/cp/typeck.c.jj	2019-03-13 21:21:27.000000000 +0100
+++ gcc/cp/typeck.c	2019-03-15 16:23:27.582046214 +0100
@@ -2443,6 +2443,16 @@ build_class_member_access_expr (cp_expr
       /* A static data member.  */
       result = member;
       mark_exp_read (object);
+
+      tree wrap;
+      if (!cp_unevaluated_operand
+	  && !processing_template_decl
+	  && CP_DECL_THREAD_LOCAL_P (result)
+	  && (wrap = get_tls_wrapper_fn (result)))
+	/* Replace an evaluated use of the thread_local variable with
+	   a call to its wrapper.  */
+	result = build_cxx_call (wrap, 0, NULL, tf_warning_or_error);
+
       /* If OBJECT has side-effects, they are supposed to occur.  */
       if (TREE_SIDE_EFFECTS (object))
 	result = build2 (COMPOUND_EXPR, TREE_TYPE (result), object, result);
--- gcc/testsuite/g++.dg/tls/thread_local11.C.jj	2019-03-15 17:02:44.752275408 +0100
+++ gcc/testsuite/g++.dg/tls/thread_local11.C	2019-03-15 17:31:19.199665422 +0100
@@ -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> ();
+}
--- gcc/testsuite/g++.dg/tls/thread_local11.h.jj	2019-03-15 17:30:31.198440309 +0100
+++ gcc/testsuite/g++.dg/tls/thread_local11.h	2019-03-15 17:31:00.667964581 +0100
@@ -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; }
--- gcc/testsuite/g++.dg/tls/thread_local12a.C.jj	2019-03-15 17:26:42.911125577 +0100
+++ gcc/testsuite/g++.dg/tls/thread_local12a.C	2019-03-15 17:33:26.482610680 +0100
@@ -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 ();
+}
--- gcc/testsuite/g++.dg/tls/thread_local12b.C.jj	2019-03-15 17:35:25.549685123 +0100
+++ gcc/testsuite/g++.dg/tls/thread_local12b.C	2019-03-15 17:33:34.781476709 +0100
@@ -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 ();
+}
--- gcc/testsuite/g++.dg/tls/thread_local12c.C.jj	2019-03-15 17:35:25.549685123 +0100
+++ gcc/testsuite/g++.dg/tls/thread_local12c.C	2019-03-15 17:33:42.843346568 +0100
@@ -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 ();
+}
--- gcc/testsuite/g++.dg/tls/thread_local12d.C.jj	2019-03-15 17:35:25.549685123 +0100
+++ gcc/testsuite/g++.dg/tls/thread_local12d.C	2019-03-15 17:33:56.433127186 +0100
@@ -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 ();
+}
--- gcc/testsuite/g++.dg/tls/thread_local12e.C.jj	2019-03-15 17:35:25.549685123 +0100
+++ gcc/testsuite/g++.dg/tls/thread_local12e.C	2019-03-15 17:34:04.892990612 +0100
@@ -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 ();
+}
--- gcc/testsuite/g++.dg/tls/thread_local12f.C.jj	2019-03-15 17:35:25.549685123 +0100
+++ gcc/testsuite/g++.dg/tls/thread_local12f.C	2019-03-15 17:34:13.534851108 +0100
@@ -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 ();
+}
--- gcc/testsuite/g++.dg/tls/thread_local12g.C.jj	2019-03-15 17:35:25.549685123 +0100
+++ gcc/testsuite/g++.dg/tls/thread_local12g.C	2019-03-15 17:34:22.050713633 +0100
@@ -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 ();
+}
--- gcc/testsuite/g++.dg/tls/thread_local12h.C.jj	2019-03-15 17:35:25.549685123 +0100
+++ gcc/testsuite/g++.dg/tls/thread_local12h.C	2019-03-15 17:34:31.316564053 +0100
@@ -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 ();
+}
--- gcc/testsuite/g++.dg/tls/thread_local12i.C.jj	2019-03-15 17:35:25.549685123 +0100
+++ gcc/testsuite/g++.dg/tls/thread_local12i.C	2019-03-15 17:34:41.387401475 +0100
@@ -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 ();
+}
--- gcc/testsuite/g++.dg/tls/thread_local12j.C.jj	2019-03-15 17:35:25.549685123 +0100
+++ gcc/testsuite/g++.dg/tls/thread_local12j.C	2019-03-15 17:34:50.933247380 +0100
@@ -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 ();
+}
--- gcc/testsuite/g++.dg/tls/thread_local12k.C.jj	2019-03-15 17:35:25.549685123 +0100
+++ gcc/testsuite/g++.dg/tls/thread_local12k.C	2019-03-15 17:35:01.798071988 +0100
@@ -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 ();
+}
--- gcc/testsuite/g++.dg/tls/thread_local12l.C.jj	2019-03-15 17:35:25.550685107 +0100
+++ gcc/testsuite/g++.dg/tls/thread_local12l.C	2019-03-15 17:35:09.352948983 +0100
@@ -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 ();
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]