From 47304c6a0b365ca21d95be5e532e8d5925ed04f3 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 29 Jun 2017 17:13:43 -0400 Subject: [PATCH] PR c++/81180 - ICE with C++17 deduction of member class template. * pt.c (build_deduction_guide): Correct member template handling. From-SVN: r249816 --- gcc/cp/ChangeLog | 3 +++ gcc/cp/pt.c | 20 +++++++++---------- .../g++.dg/cpp1z/class-deduction40.C | 19 ++++++++++++++++++ 3 files changed, 31 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1z/class-deduction40.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0fae3cd6684..5549f720141 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2017-06-29 Jason Merrill + 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. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 047d3baabbf..3ecacbd62de 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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 index 00000000000..eeffa69adf5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction40.C @@ -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; +} + -- 2.30.2