PR c++/81180 - ICE with C++17 deduction of member class template.
authorJason Merrill <jason@redhat.com>
Thu, 29 Jun 2017 21:13:43 +0000 (17:13 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 29 Jun 2017 21:13:43 +0000 (17:13 -0400)
* pt.c (build_deduction_guide): Correct member template handling.

From-SVN: r249816

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

index 0fae3cd66840d344b766ecfe8618884d91dd1bc2..5549f720141f3cafef75074c3d2b1b79ed1b20c5 100644 (file)
@@ -1,5 +1,8 @@
 2017-06-29  Jason Merrill  <jason@redhat.com>
 
+       PR c++/81180 - ICE with C++17 deduction of member class template.
+       * pt.c (build_deduction_guide): Correct member template handling.
+
        PR c++/81188 - matching decltype of member function call.
        * tree.c (cp_tree_equal): Remove COMPONENT_REF special case.
 
index 047d3baabbfeda2b2e69f8fe44cfa0f7ab6d3067..3ecacbd62de3ecfc859a7477a9d4b2c461b0f55a 100644 (file)
@@ -25216,17 +25216,16 @@ build_deduction_guide (tree ctor, tree outer_args, tsubst_flags_t complain)
     }
   else
     {
+      ++processing_template_decl;
+
+      tree fn_tmpl
+       = (TREE_CODE (ctor) == TEMPLATE_DECL ? ctor
+          : DECL_TI_TEMPLATE (ctor));
       if (outer_args)
-       ctor = tsubst (ctor, outer_args, complain, ctor);
+       fn_tmpl = tsubst (fn_tmpl, outer_args, complain, ctor);
+      ctor = DECL_TEMPLATE_RESULT (fn_tmpl);
+
       type = DECL_CONTEXT (ctor);
-      tree fn_tmpl;
-      if (TREE_CODE (ctor) == TEMPLATE_DECL)
-       {
-         fn_tmpl = ctor;
-         ctor = DECL_TEMPLATE_RESULT (fn_tmpl);
-       }
-      else
-       fn_tmpl = DECL_TI_TEMPLATE (ctor);
 
       tparms = DECL_TEMPLATE_PARMS (fn_tmpl);
       /* If type is a member class template, DECL_TI_ARGS (ctor) will have
@@ -25248,7 +25247,6 @@ build_deduction_guide (tree ctor, tree outer_args, tsubst_flags_t complain)
          /* For a member template constructor, we need to flatten the two
             template parameter lists into one, and then adjust the function
             signature accordingly.  This gets...complicated.  */
-         ++processing_template_decl;
          tree save_parms = current_template_parms;
 
          /* For a member template we should have two levels of parms/args, one
@@ -25309,8 +25307,8 @@ build_deduction_guide (tree ctor, tree outer_args, tsubst_flags_t complain)
            ci = tsubst_constraint_info (ci, tsubst_args, complain, ctor);
 
          current_template_parms = save_parms;
-         --processing_template_decl;
        }
+      --processing_template_decl;
     }
 
   if (!memtmpl)
diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction40.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction40.C
new file mode 100644 (file)
index 0000000..eeffa69
--- /dev/null
@@ -0,0 +1,19 @@
+// PR c++/81180
+// { dg-options -std=c++1z }
+
+template < int I > struct int_{};
+
+template < typename T >
+struct A{
+    template < typename U, int I >
+    struct B{
+        B(U u, int_< I >){}
+    };
+};
+
+
+int main(){
+    A< int >::B v(0, int_< 0 >());
+    (void)v;
+}
+