This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix ICE with GNU TLS var in a template (PR c++/66808, PR c++/69000)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Jason Merrill <jason at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Tue, 22 Dec 2015 09:04:30 +0100
- Subject: [C++ PATCH] Fix ICE with GNU TLS var in a template (PR c++/66808, PR c++/69000)
- Authentication-results: sourceware.org; auth=none
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
The following testcases ICE because tsubst_decl seems to assume
templates of local VAR_DECLs don't have DECL_LANG_SPECIFIC set for them,
but for GNU TLS vars they do, yet nothing clears DECL_TEMPLATE_INFO
in the DEC_LANG_SPECIFIC copy. The stale DECL_TEMPLATE_INFO then
causes mangling to give up as if the var hasn't been instantiated.
For the !local_p case tsubst_decl will set DECL_TEMPLATE_INFO to
something new.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2015-12-22 Jakub Jelinek <jakub@redhat.com>
PR c++/66808
PR c++/69000
* pt.c (tsubst_decl): For local_p VAR_DECLs, clear
DECL_LANG_SPECIFIC (r).
* g++.dg/tls/pr66808.C: New test.
* g++.dg/tls/pr69000.C: New test.
--- gcc/cp/pt.c.jj 2015-12-17 14:49:34.000000000 +0100
+++ gcc/cp/pt.c 2015-12-21 14:11:24.411320263 +0100
@@ -12183,6 +12183,8 @@ tsubst_decl (tree t, tree args, tsubst_f
DECL_TEMPLATE_INSTANTIATED (r) = 0;
if (type == error_mark_node)
RETURN (error_mark_node);
+ if (DECL_LANG_SPECIFIC (r) && local_p)
+ DECL_TEMPLATE_INFO (r) = NULL_TREE;
if (TREE_CODE (type) == FUNCTION_TYPE)
{
/* It may seem that this case cannot occur, since:
--- gcc/testsuite/g++.dg/tls/pr69000.C.jj 2015-12-21 14:03:38.362847547 +0100
+++ gcc/testsuite/g++.dg/tls/pr69000.C 2015-12-21 14:04:17.839291295 +0100
@@ -0,0 +1,19 @@
+// PR c++/69000
+// { dg-do compile }
+// { dg-require-effective-target tls }
+
+class A {};
+
+template <typename T>
+struct B
+{
+ static int *& foo () { static __thread int *c = 0; return c; }
+};
+
+B<A> d;
+
+void
+bar ()
+{
+ d.foo ();
+}
--- gcc/testsuite/g++.dg/tls/pr66808.C.jj 2015-12-21 14:06:06.791756074 +0100
+++ gcc/testsuite/g++.dg/tls/pr66808.C 2015-12-21 14:06:02.651814409 +0100
@@ -0,0 +1,10 @@
+// PR c++/66808
+// { dg-do compile { target c++11 } }
+// { dg-require-effective-target tls }
+
+template <typename>
+class A {
+ int *b = foo ();
+ int *foo () { static __thread int a; return &a; }
+};
+A<int> b;
Jakub