PR c++/88869 - C++17 ICE with CTAD and explicit specialization.
authorJason Merrill <jason@redhat.com>
Fri, 22 Feb 2019 02:08:05 +0000 (21:08 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 22 Feb 2019 02:08:05 +0000 (21:08 -0500)
The members of an explicit specialization of a class template don't have the
template parameters of that class template, so we shouldn't try to provide
arguments for them.  Only set outer_args when the class is an instantiation.

* pt.c (do_class_deduction): Don't include explicit specialization
args in outer_args.

From-SVN: r269093

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp1z/class-deduction63.C [new file with mode: 0644]

index 2f99f2b95c8b53b69d631654dac1a1271eddf0ce..013bca5938027c6d06f05ca1b4d710072fb200b0 100644 (file)
@@ -1,5 +1,9 @@
 2019-02-21  Jason Merrill  <jason@redhat.com>
 
+       PR c++/88869 - C++17 ICE with CTAD and explicit specialization.
+       * pt.c (do_class_deduction): Don't include explicit specialization
+       args in outer_args.
+
        PR c++/89422 - ICE with -g and lambda in default arg in template.
        * pt.c (tsubst_function_decl): SET_DECL_FRIEND_CONTEXT sooner.
 
index 76fb625a06847e5eee0ceeae69576d1f71f9f802..42dd095a6b010ba63bd2f14d1084568886465dfe 100644 (file)
@@ -27224,7 +27224,7 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags,
 
   tree outer_args = NULL_TREE;
   if (DECL_CLASS_SCOPE_P (tmpl)
-      && CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (tmpl)))
+      && CLASSTYPE_TEMPLATE_INSTANTIATION (DECL_CONTEXT (tmpl)))
     {
       outer_args = CLASSTYPE_TI_ARGS (DECL_CONTEXT (tmpl));
       type = TREE_TYPE (most_general_template (tmpl));
diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction63.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction63.C
new file mode 100644 (file)
index 0000000..4fc66fc
--- /dev/null
@@ -0,0 +1,11 @@
+// PR c++/88869
+// { dg-do compile { target c++17 } }
+
+template <typename> struct B;
+template <> struct B<int> {
+  template <typename T> struct C {
+    T e;
+    C (T f) : e(f) {}
+  };
+  void foo () { C c (42); }
+};