aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2014-08-26 15:39:36 -0400
committerJason Merrill <jason@gcc.gnu.org>2014-08-26 15:39:36 -0400
commit71d64cd435526ba6470a84f6b7e0a3ee3cac790c (patch)
tree8447e46f6e36b2d26eba2c8ce315826c9f73307a /gcc
parent61aa0978e2caf0417a78289eed85010b0c11be94 (diff)
downloadgcc-71d64cd435526ba6470a84f6b7e0a3ee3cac790c.zip
gcc-71d64cd435526ba6470a84f6b7e0a3ee3cac790c.tar.gz
gcc-71d64cd435526ba6470a84f6b7e0a3ee3cac790c.tar.bz2
re PR middle-end/58624 (gcc internal compiler error: Segmentaion fault in insert_to_assembler_name_hash)
PR c++/58624 * pt.c (tsubst_decl) [VAR_DECL]: Copy TLS model. (tsubst_copy_and_build) [VAR_DECL]: Use TLS wrapper. * semantics.c (finish_id_expression): Don't call TLS wrapper in a template. From-SVN: r214543
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/pt.c13
-rw-r--r--gcc/cp/semantics.c1
-rw-r--r--gcc/testsuite/g++.dg/tls/thread_local10.C23
4 files changed, 45 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 04394c3..388293a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2014-08-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/58624
+ * pt.c (tsubst_decl) [VAR_DECL]: Copy TLS model.
+ (tsubst_copy_and_build) [VAR_DECL]: Use TLS wrapper.
+ * semantics.c (finish_id_expression): Don't call TLS wrapper in a
+ template.
+
2014-08-25 Jason Merrill <jason@redhat.com>
* pt.c (check_explicit_specialization): Don't complain about
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 59df387..eac837f 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -11225,6 +11225,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
}
SET_DECL_VALUE_EXPR (r, ve);
}
+ if (TREE_STATIC (r) || DECL_EXTERNAL (r))
+ set_decl_tls_model (r, decl_tls_model (t));
}
else if (DECL_SELF_REFERENCE_P (t))
SET_DECL_SELF_REFERENCE_P (r);
@@ -15410,6 +15412,17 @@ tsubst_copy_and_build (tree t,
case PARM_DECL:
{
tree r = tsubst_copy (t, args, complain, in_decl);
+ if (VAR_P (r)
+ && !processing_template_decl
+ && !cp_unevaluated_operand
+ && (TREE_STATIC (r) || DECL_EXTERNAL (r))
+ && 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_CODE (TREE_TYPE (t)) != REFERENCE_TYPE)
/* If the original type was a reference, we'll be wrapped in
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 16abad0..9c9fc1c 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -3500,6 +3500,7 @@ finish_id_expression (tree id_expression,
tree wrap;
if (VAR_P (decl)
&& !cp_unevaluated_operand
+ && !processing_template_decl
&& (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
&& DECL_THREAD_LOCAL_P (decl)
&& (wrap = get_tls_wrapper_fn (decl)))
diff --git a/gcc/testsuite/g++.dg/tls/thread_local10.C b/gcc/testsuite/g++.dg/tls/thread_local10.C
new file mode 100644
index 0000000..48c1b86
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tls/thread_local10.C
@@ -0,0 +1,23 @@
+// PR c++/58624
+
+// { dg-do run { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+
+int i;
+
+template <typename> struct A
+{
+ static thread_local int s;
+
+ A () { i = s; }
+};
+
+int f() { return 42; }
+template <typename T> thread_local int A<T>::s = f();
+
+int main () {
+ A<void> a;
+ if (i != 42)
+ __builtin_abort();
+}