aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2019-03-22 15:42:57 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2019-03-22 15:42:57 +0100
commit5c3703c552d12e7e62febf4fe5deb837a1305f78 (patch)
tree34ce504ac15714e9dbd07318be4a9cfce6c3c7b5 /gcc
parenta15ffa22b5b541a385e509649dc39db59492bcdb (diff)
downloadgcc-5c3703c552d12e7e62febf4fe5deb837a1305f78.zip
gcc-5c3703c552d12e7e62febf4fe5deb837a1305f78.tar.gz
gcc-5c3703c552d12e7e62febf4fe5deb837a1305f78.tar.bz2
re PR c++/60702 (thread_local initialization)
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: r269875
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/decl2.c18
-rw-r--r--gcc/cp/pt.c15
-rw-r--r--gcc/cp/semantics.c18
-rw-r--r--gcc/cp/typeck.c6
-rw-r--r--gcc/testsuite/ChangeLog16
-rw-r--r--gcc/testsuite/g++.dg/tls/thread_local11.C48
-rw-r--r--gcc/testsuite/g++.dg/tls/thread_local11.h26
-rw-r--r--gcc/testsuite/g++.dg/tls/thread_local12a.C12
-rw-r--r--gcc/testsuite/g++.dg/tls/thread_local12b.C12
-rw-r--r--gcc/testsuite/g++.dg/tls/thread_local12c.C12
-rw-r--r--gcc/testsuite/g++.dg/tls/thread_local12d.C12
-rw-r--r--gcc/testsuite/g++.dg/tls/thread_local12e.C12
-rw-r--r--gcc/testsuite/g++.dg/tls/thread_local12f.C12
-rw-r--r--gcc/testsuite/g++.dg/tls/thread_local12g.C12
-rw-r--r--gcc/testsuite/g++.dg/tls/thread_local12h.C12
-rw-r--r--gcc/testsuite/g++.dg/tls/thread_local12i.C12
-rw-r--r--gcc/testsuite/g++.dg/tls/thread_local12j.C12
-rw-r--r--gcc/testsuite/g++.dg/tls/thread_local12k.C12
-rw-r--r--gcc/testsuite/g++.dg/tls/thread_local12l.C12
21 files changed, 279 insertions, 25 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 71f9d67..16f1b8e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,16 @@
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.
+
PR c++/87481
* constexpr.c (struct constexpr_ctx): Add constexpr_ops_count member.
(cxx_eval_constant_expression): When not skipping, not constant class
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 15e39e1..3fe91ad 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6513,7 +6513,7 @@ extern tree cp_build_parm_decl (tree, 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);
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index f8637da..6f23ee1 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -3442,7 +3442,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. */
@@ -3496,6 +3496,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() {
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 6c15419..afb7ece 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -19403,17 +19403,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);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 599e0e3..15b766d 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2143,6 +2143,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);
}
@@ -3788,18 +3790,10 @@ finish_id_expression_1 (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
&& !dependent_p
&& variable_template_p (TREE_OPERAND (decl, 0)))
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index f77e9c6..e2c5fc2 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -2443,6 +2443,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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index febe7b3..8324702 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,21 @@
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.
+
PR c++/87481
* g++.dg/cpp1y/constexpr-87481.C: New test.
diff --git a/gcc/testsuite/g++.dg/tls/thread_local11.C b/gcc/testsuite/g++.dg/tls/thread_local11.C
new file mode 100644
index 0000000..036d91a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tls/thread_local11.C
@@ -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
index 0000000..761b42d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tls/thread_local11.h
@@ -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
index 0000000..87a1716
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tls/thread_local12a.C
@@ -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
index 0000000..498bace
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tls/thread_local12b.C
@@ -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
index 0000000..92add8f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tls/thread_local12c.C
@@ -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
index 0000000..7863136
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tls/thread_local12d.C
@@ -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
index 0000000..95c44f7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tls/thread_local12e.C
@@ -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
index 0000000..e7795dc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tls/thread_local12f.C
@@ -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
index 0000000..c7c964a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tls/thread_local12g.C
@@ -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
index 0000000..32b6841
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tls/thread_local12h.C
@@ -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
index 0000000..815e14e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tls/thread_local12i.C
@@ -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
index 0000000..0009de1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tls/thread_local12j.C
@@ -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
index 0000000..589e872
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tls/thread_local12k.C
@@ -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
index 0000000..273e1be
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tls/thread_local12l.C
@@ -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 ();
+}