diff mbox

Fix PR c++/66686 (dependent template template substitution)

Message ID 1435430233-12716-1-git-send-email-patrick@parcs.ath.cx
State New
Headers show

Commit Message

Patrick Palka June 27, 2015, 6:37 p.m. UTC
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

Comments

Patrick Palka June 30, 2015, 7:46 p.m. UTC | #1
On Sat, Jun 27, 2015 at 2:37 PM, Patrick Palka <patrick@parcs.ath.cx> wrote:
> 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
>

Early ping because I forgot to CC Jason.
Jason Merrill June 30, 2015, 9:39 p.m. UTC | #2
OK.

Jason
diff mbox

Patch

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;