diff options
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/pt.c | 28 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/ttp31.C | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/ttp32.C | 10 |
4 files changed, 47 insertions, 8 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 067d538..a4ffc66 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2018-03-14 Jason Merrill <jason@redhat.com> + + PR c++/83916 - ICE with template template parameters. + * pt.c (convert_template_argument): Don't substitute into type of + non-type parameter if we don't have enough arg levels. + (unify): Likewise. + 2018-03-14 Marek Polacek <polacek@redhat.com> PR c++/84596 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index d720c33..1432181 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -7974,7 +7974,11 @@ convert_template_argument (tree parm, { tree t = TREE_TYPE (parm); - if (tree a = type_uses_auto (t)) + if (TEMPLATE_PARM_LEVEL (get_template_parm_index (parm)) + > TMPL_ARGS_DEPTH (args)) + /* We don't have enough levels of args to do any substitution. This + can happen in the context of -fnew-ttp-matching. */; + else if (tree a = type_uses_auto (t)) { t = do_auto_deduction (t, arg, a, complain, adc_unify, args); if (t == error_mark_node) @@ -21224,14 +21228,22 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, template-parameter exactly, except that a template-argument deduced from an array bound may be of any integral type. The non-type parameter might use already deduced type parameters. */ - ++processing_template_decl; - tparm = tsubst (TREE_TYPE (parm), targs, 0, NULL_TREE); - --processing_template_decl; - if (tree a = type_uses_auto (tparm)) + tparm = TREE_TYPE (parm); + if (TEMPLATE_PARM_LEVEL (parm) > TMPL_ARGS_DEPTH (targs)) + /* We don't have enough levels of args to do any substitution. This + can happen in the context of -fnew-ttp-matching. */; + else { - tparm = do_auto_deduction (tparm, arg, a, complain, adc_unify); - if (tparm == error_mark_node) - return 1; + ++processing_template_decl; + tparm = tsubst (tparm, targs, tf_none, NULL_TREE); + --processing_template_decl; + + if (tree a = type_uses_auto (tparm)) + { + tparm = do_auto_deduction (tparm, arg, a, complain, adc_unify); + if (tparm == error_mark_node) + return 1; + } } if (!TREE_TYPE (arg)) diff --git a/gcc/testsuite/g++.dg/template/ttp31.C b/gcc/testsuite/g++.dg/template/ttp31.C new file mode 100644 index 0000000..ff3f1f5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp31.C @@ -0,0 +1,10 @@ +// PR c++/83916 +// { dg-do compile { target c++11 } } + +template<class TA, + template<TA...> class TTA, TA... VA> +struct A { }; + +template<class UC, class TC, + template<TC...> class TTC, TC... VC> +struct C : A<TC, TTC, VC...> { }; diff --git a/gcc/testsuite/g++.dg/template/ttp32.C b/gcc/testsuite/g++.dg/template/ttp32.C new file mode 100644 index 0000000..a96a62d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp32.C @@ -0,0 +1,10 @@ +// PR c++/83916 +// { dg-do compile { target c++17 } } + +template<class TA, + template<auto...> class TTA, TA... VA> +struct A { }; + +template<class UC, class TC, + template<auto...> class TTC, TC... VC> +struct C : A<TC, TTC, VC...> { }; |