diff mbox series

C++ PATCH for c++/86171, ICE with recursive alias instantiation

Message ID CADzB+2=MB6bYKAUnTBq7Uh4B+9eGvRJnCpaSaekcY3f4h8qcrQ@mail.gmail.com
State New
Headers show
Series C++ PATCH for c++/86171, ICE with recursive alias instantiation | expand

Commit Message

Jason Merrill June 18, 2018, 6:14 p.m. UTC
Here, instantiating B<short> requires instantiating A<short>, which
requires instantiating B<short>.  Previously, that resulted in
creating two separate TYPE_DECLS for B<short> and trying to combine
them in register_specialization.  Better, I think, to check for this
situation sooner.

Tested x86_64-pc-linux-gnu, applying to trunk.
diff mbox series

Patch

commit f82ab957170984838b0bf4d9f7ef5d254eec28c3
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Jun 18 11:53:39 2018 -0400

            PR c++/86171 - ICE with recursive alias instantiation.
    
            * pt.c (tsubst_decl): Handle recursive alias instantiation.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 4ee84b201e9..6e590d4d342 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -13639,7 +13639,6 @@  tsubst_decl (tree t, tree args, tsubst_flags_t complain)
 	  }
 
 	/* Create a new node for the specialization we need.  */
-	r = copy_decl (t);
 	if (type == NULL_TREE)
 	  {
 	    if (is_typedef_decl (t))
@@ -13664,7 +13663,16 @@  tsubst_decl (tree t, tree args, tsubst_flags_t complain)
 		  sub_args = strip_innermost_template_args (args, extra);
 	      }
 	    type = tsubst (type, sub_args, complain, in_decl);
+	    /* Substituting the type might have recursively instantiated this
+	       same alias (c++/86171).  */
+	    if (gen_tmpl && DECL_ALIAS_TEMPLATE_P (gen_tmpl)
+		&& (spec = retrieve_specialization (gen_tmpl, argvec, hash)))
+	      {
+		r = spec;
+		break;
+	      }
 	  }
+	r = copy_decl (t);
 	if (VAR_P (r))
 	  {
 	    DECL_INITIALIZED_P (r) = 0;
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-65.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-65.C
new file mode 100644
index 00000000000..e320f3eedd0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-65.C
@@ -0,0 +1,10 @@ 
+// PR c++/86171
+// { dg-do compile { target c++11 } }
+
+template <class> struct A;
+template <class T> using B = typename A<T>::X;
+template <class T> struct A {
+  typedef int X;
+  typedef B<T> U;
+};
+B<short> b;