This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++ PATCH] Fix ICE in unify with variadic templates (PRs c++/32565, c++/33943)


On Thu, Nov 15, 2007 at 07:40:42AM -0500, Jakub Jelinek wrote:
> As shown on these I believe valid testcases, when unifying
> BOUND_TEMPLATE_TEMPLATE_PARMs, we really can't assume if one {parm,arg}vec
> argument is a parameter pack, the other will be as well.  Fixed by using
> expand_template_argument_pack on both vectors so that we unify corresponding
> parameters.

This updated patch also handles PACK_EXPANSION_P if present at the end of
this way expanded parmvec.  With this PR33943 no longer ICEs, the errors are
now:
/usr/src/gcc/gcc/testsuite/g++.dg/cpp0x/variadic86.C:18: error: cannot expand 'U ...' into a fixed-length argument list
/usr/src/gcc/gcc/testsuite/g++.dg/cpp0x/variadic86.C:18: error: ambiguous class template instantiation for 'struct baz<foo<int, short int> >'
/usr/src/gcc/gcc/testsuite/g++.dg/cpp0x/variadic86.C:12: error: candidates are: struct baz<T<U ...> >
/usr/src/gcc/gcc/testsuite/g++.dg/cpp0x/variadic86.C:16: error:                 struct baz<T<U, V ...> >
/usr/src/gcc/gcc/testsuite/g++.dg/cpp0x/variadic86.C:18: error: aggregate 'baz<foo<int, short int> > b1' has incomplete type and cannot be defined
/usr/src/gcc/gcc/testsuite/g++.dg/cpp0x/variadic86.C:19: error: cannot expand 'U ...' into a fixed-length argument list
(though they aren't issued by the unify with BOUND_TEMPLATE_TEMPLATE_PARM
that has been changed, but later on).  Now whether the errors are
correct or not I don't know.

2007-11-19  Jakub Jelinek  <jakub@redhat.com>

	PR c++/32565
	PR c++/33943
	* pt.c (unify) <case BOUND_TEMPLATE_TEMPLATE_PARM>: Expand both
	parmvec and argvec with expand_template_argument_pack.  Handle
	PACK_EXPANSION_P at the end of parmvec.

	* g++.dg/cpp0x/variadic84.C: New test.
	* g++.dg/cpp0x/variadic85.C: New test.
	* g++.dg/cpp0x/variadic86.C: New test.

--- gcc/cp/pt.c.jj	2007-11-18 20:14:58.000000000 +0100
+++ gcc/cp/pt.c	2007-11-19 09:48:36.000000000 +0100
@@ -12684,7 +12684,8 @@ unify (tree tparms, tree targs, tree par
 	    tree argvec = INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (arg));
 	    tree argtmplvec
 	      = DECL_INNERMOST_TEMPLATE_PARMS (TYPE_TI_TEMPLATE (arg));
-	    int i;
+	    int i, len;
+	    int parm_variadic_p = 0;
 
 	    /* The resolution to DR150 makes clear that default
 	       arguments for an N-argument may not be used to bind T
@@ -12726,7 +12727,19 @@ unify (tree tparms, tree targs, tree par
 	       rather than the whole TREE_VEC since they can have
 	       different number of elements.  */
 
-	    for (i = 0; i < TREE_VEC_LENGTH (parmvec); ++i)
+	    parmvec = expand_template_argument_pack (parmvec);
+	    argvec = expand_template_argument_pack (argvec);
+
+	    len = TREE_VEC_LENGTH (parmvec);
+	    /* Check if the parameters end in a pack, making them variadic.  */
+	    if (len > 0
+		&& PACK_EXPANSION_P (TREE_VEC_ELT (parmvec, len - 1)))
+	      parm_variadic_p = 1;
+
+	    if (TREE_VEC_LENGTH (argvec) < len - parm_variadic_p)
+	      return 1;
+
+	    for (i = 0; i < len - parm_variadic_p; ++i)
 	      {
 		if (unify (tparms, targs,
 			   TREE_VEC_ELT (parmvec, i),
@@ -12734,6 +12747,14 @@ unify (tree tparms, tree targs, tree par
 			   UNIFY_ALLOW_NONE))
 		  return 1;
 	      }
+
+	    if (parm_variadic_p
+		&& unify_pack_expansion (tparms, targs, 
+					 parmvec, argvec,
+					 UNIFY_ALLOW_NONE,
+					 /*call_args_p=*/false,
+					 /*subr=*/false))
+	      return 1;
 	  }
 	  arg = TYPE_TI_TEMPLATE (arg);
 
--- gcc/testsuite/g++.dg/cpp0x/variadic84.C.jj	2007-11-19 08:27:59.000000000 +0100
+++ gcc/testsuite/g++.dg/cpp0x/variadic84.C	2007-11-19 08:27:59.000000000 +0100
@@ -0,0 +1,26 @@
+// PR c++/32565
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template<typename...> struct A1;
+template<template<int...> class T> struct A1<T<0> > {};
+template<typename...> struct A2;
+template<template<int...> class T> struct A2<T<0, 1> > {};
+template<typename...> struct A3;
+template<template<int, int...> class T> struct A3<T<0, 1> > {};
+template<typename...> struct A4;
+template<template<typename...> class T> struct A4<T<int> > {};
+template<typename...> struct A5;
+template<template<typename...> class T> struct A5<T<int, long> > {};
+template<typename...> struct A6;
+template<template<typename, typename...> class T> struct A6<T<int, long> > {};
+template<int> struct B1 {};
+template<int, int> struct B2 {};
+template<typename> struct B3 {};
+template<typename, typename> struct B4 {};
+A1<B1<0> > a1;
+A2<B2<0, 1> > a2;
+A3<B2<0, 1> > a3;
+A4<B3<int> > a4;
+A5<B4<int, long> > a5;
+A6<B4<int, long> > a6;
--- gcc/testsuite/g++.dg/cpp0x/variadic85.C.jj	2007-11-19 08:27:59.000000000 +0100
+++ gcc/testsuite/g++.dg/cpp0x/variadic85.C	2007-11-19 08:27:59.000000000 +0100
@@ -0,0 +1,10 @@
+// PR c++/32565
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template<typename...> struct A1;
+template<template<int, int...> class T> struct A1<T<0, 1> > {};
+template<int, int, int...> struct B1 {};
+A1<B1<0, 1> > a1;
+template<int...> struct B2 {};
+A1<B2<0, 1> > a2;
--- gcc/testsuite/g++.dg/cpp0x/variadic86.C.jj	2007-11-19 10:02:14.000000000 +0100
+++ gcc/testsuite/g++.dg/cpp0x/variadic86.C	2007-11-19 10:03:01.000000000 +0100
@@ -0,0 +1,19 @@
+// PR c++/33943
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template<typename... A> struct foo {};
+
+template<typename A0, typename... A1> struct bar {};
+
+template<typename U> struct baz;
+
+template<template<typename...> class T, typename... U> struct baz< T<U...> >
+{};				// { dg-error "struct baz" }
+
+template<template<typename, typename...> class T, typename U, typename... V>
+struct baz< T<U, V...> >
+{};				// { dg-error "struct baz" }
+
+baz< foo<int, short> > b1;	// { dg-error "cannot expand|ambiguous class template instantiation|has incomplete type" }
+baz< bar<int, short> > b2;	// { dg-error "cannot expand" }


	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]