This patch makes coerce_template_template_parm consider a coercion successful if the result of calling tsubst on a template template parm is a dependent type even when the desired argument type is non-dependent.
For the test case below, TREE_TYPE (parm) is B and TREE_TYPE (arg) is int. After calling tsubst on the parm the resulting type is still B, a dependent type. Without checking that the resulting type is dependent, the function would return 0 because same_type_p would return false. Bootstrap + regtest of this change was successful on x86_64-unknown-linux-gnu. Does this patch look OK? gcc/cp/ChangeLog: * pt.c (coerce_template_template_parm) [PARM_DECL]: Don't return 0 if tsubst returns a dependent type. gcc/testsuite/ChangeLog: * g++.dg/template/pr66686.C: New test. --- gcc/cp/pt.c | 12 +++++++----- gcc/testsuite/g++.dg/template/pr66686.C | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/pr66686.C diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 2b37460..d7768a8 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -6357,11 +6357,13 @@ coerce_template_template_parm (tree parm, D<int, C> d; i.e. the parameter list of TT depends on earlier parameters. */ - if (!uses_template_parms (TREE_TYPE (arg)) - && !same_type_p - (tsubst (TREE_TYPE (parm), outer_args, complain, in_decl), - TREE_TYPE (arg))) - return 0; + if (!uses_template_parms (TREE_TYPE (arg))) + { + tree t = tsubst (TREE_TYPE (parm), outer_args, complain, in_decl); + if (!uses_template_parms (t) + && !same_type_p (t, TREE_TYPE (arg))) + return 0; + } if (TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (arg)) && !TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm))) diff --git a/gcc/testsuite/g++.dg/template/pr66686.C b/gcc/testsuite/g++.dg/template/pr66686.C new file mode 100644 index 0000000..d8aea62 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pr66686.C @@ -0,0 +1,15 @@ +// PR c++/66686 + +template <int> +struct Y { }; + +template <class B, template <template <B> class Z> class C> +struct X +{ + C<Y> a; // { dg-bogus "mismatch" } +}; + +template <template <int> class> +struct A { }; + +X<int, A> a; -- 2.5.0.rc0.5.g91e10c5.dirty