c++: Revert alias template change [pr95263]
authorNathan Sidwell <nathan@acm.org>
Wed, 27 May 2020 13:50:15 +0000 (09:50 -0400)
committerNathan Sidwell <nathan@acm.org>
Wed, 27 May 2020 13:58:48 +0000 (09:58 -0400)
Turns out templates are more complicated than you think, even when you
know they are more complicated than you think.  Reverting this change.

PR c++/95263
* pt.c (lookup_template_class_1): Restore alias template mutation.

gcc/cp/pt.c
gcc/testsuite/g++.dg/template/pr95263.C [new file with mode: 0644]

index c17a038c6d0100288b8b84d2e9f066ce8f87f45c..4d9651acee65be392a53fc004cbb9cb94c0ed88d 100644 (file)
@@ -10062,21 +10062,8 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
            }
        }
 
-      /* Build template info for the new specialization.  This can
-        overwrite the existing TEMPLATE_INFO for T (that points to
-        its instantiated TEMPLATE_DECL), with this one that points to
-        the most general template, but that's what we want.  */
-
-      if (TYPE_ALIAS_P (t))
-       {
-         /* This should already have been constructed during
-            instantiation of the alias decl.  */
-         tree ti = DECL_TEMPLATE_INFO (TYPE_NAME (t));
-         gcc_checking_assert (template_args_equal (TI_ARGS (ti), arglist)
-                              && TI_TEMPLATE (ti) == found);
-       }
-      else
-       SET_TYPE_TEMPLATE_INFO (t, build_template_info (found, arglist));
+      // Build template info for the new specialization.
+      SET_TYPE_TEMPLATE_INFO (t, build_template_info (found, arglist));
 
       elt.spec = t;
       slot = type_specializations->find_slot_with_hash (&elt, hash, INSERT);
diff --git a/gcc/testsuite/g++.dg/template/pr95263.C b/gcc/testsuite/g++.dg/template/pr95263.C
new file mode 100644 (file)
index 0000000..08a1b87
--- /dev/null
@@ -0,0 +1,23 @@
+// { dg-do compile { target c++11 } }
+// PR C++/95263
+// ICE on alias template instantiation
+
+template <typename> class TPL {
+  template <int> using INT = int;
+};
+
+template <typename T> class Klass
+{
+public:
+  template <int I> using ALIAS = typename TPL<T>::INT<I>;
+
+  template <int> static void FUNC (); // OK
+
+  template <int I, typename> static ALIAS<I> FUNC (); // SFINAE ICE
+};
+
+void Fn ()
+{
+  Klass<int>::FUNC<0> ();
+}
+