diff mbox

[C++] PR 54377

Message ID 53ECE07E.1080409@oracle.com
State New
Headers show

Commit Message

Paolo Carlini Aug. 14, 2014, 4:14 p.m. UTC
Hi,

On 08/14/2014 04:18 PM, Jason Merrill wrote:
> On 08/14/2014 07:14 AM, Paolo Carlini wrote:
>> +              nparms -= variadic_p ? variadic_p : default_p;
>
> What if you have both default arguments and parameter packs?
Right. Got distracted by the minor secondary issues...

It seems to me that simply adding the counters works, ie, in the 
additional cpp0x testcase we thus say 'at least 2', instead of a wrong 
'at least 3'.

I'm finishing testing the below.

Thanks,
Paolo.

/////////////////////

Comments

Jason Merrill Aug. 14, 2014, 4:45 p.m. UTC | #1
OK.

Jason
diff mbox

Patch

Index: cp/pt.c
===================================================================
--- cp/pt.c	(revision 213952)
+++ cp/pt.c	(working copy)
@@ -6861,19 +6861,24 @@  coerce_template_parms (tree parms,
   int variadic_args_p = 0;
   int post_variadic_parms = 0;
 
+  /* Likewise for parameters with default arguments.  */
+  int default_p = 0;
+
   if (args == error_mark_node)
     return error_mark_node;
 
   nparms = TREE_VEC_LENGTH (parms);
 
-  /* Determine if there are any parameter packs.  */
+  /* Determine if there are any parameter packs or default arguments.  */
   for (parm_idx = 0; parm_idx < nparms; ++parm_idx)
     {
-      tree tparm = TREE_VALUE (TREE_VEC_ELT (parms, parm_idx));
+      tree parm = TREE_VEC_ELT (parms, parm_idx);
       if (variadic_p)
 	++post_variadic_parms;
-      if (template_parameter_pack_p (tparm))
+      if (template_parameter_pack_p (TREE_VALUE (parm)))
 	++variadic_p;
+      if (TREE_PURPOSE (parm))
+	++default_p;
     }
 
   inner_args = orig_inner_args = INNERMOST_TEMPLATE_ARGS (args);
@@ -6902,11 +6907,11 @@  coerce_template_parms (tree parms,
     {
       if (complain & tf_error)
 	{
-          if (variadic_p)
+          if (variadic_p || default_p)
             {
-              nparms -= variadic_p;
+              nparms -= variadic_p + default_p;
 	      error ("wrong number of template arguments "
-		     "(%d, should be %d or more)", nargs, nparms);
+		     "(%d, should be at least %d)", nargs, nparms);
             }
 	  else
 	     error ("wrong number of template arguments "
@@ -6913,7 +6918,7 @@  coerce_template_parms (tree parms,
 		    "(%d, should be %d)", nargs, nparms);
 
 	  if (in_decl)
-	    error ("provided for %q+D", in_decl);
+	    inform (input_location, "provided for %q+D", in_decl);
 	}
 
       return error_mark_node;
Index: testsuite/g++.dg/cpp0x/alias-decl-2.C
===================================================================
--- testsuite/g++.dg/cpp0x/alias-decl-2.C	(revision 213952)
+++ testsuite/g++.dg/cpp0x/alias-decl-2.C	(working copy)
@@ -22,7 +22,7 @@  template<class T> using Vec = Vector<T, Alloc<T> >
 
 template<class T> void g(Vector<T, Alloc<T> >);
 
-template<template<class T> class TT> void h(TT<int>); // { dg-error "provided for" }
+template<template<class T> class TT> void h(TT<int>); // { dg-message "provided for" }
 
 void
 bar()
Index: testsuite/g++.dg/cpp0x/pr51226.C
===================================================================
--- testsuite/g++.dg/cpp0x/pr51226.C	(revision 213952)
+++ testsuite/g++.dg/cpp0x/pr51226.C	(working copy)
@@ -1,7 +1,7 @@ 
 // PR c++/51226
 // { dg-do compile { target c++11 } }
 
-template<int> struct A           // { dg-error "provided" }
+template<int> struct A           // { dg-message "provided" }
 {
   enum E : int;
 };
Index: testsuite/g++.dg/cpp0x/pr54377.C
===================================================================
--- testsuite/g++.dg/cpp0x/pr54377.C	(revision 0)
+++ testsuite/g++.dg/cpp0x/pr54377.C	(working copy)
@@ -0,0 +1,7 @@ 
+// PR c++/54377
+// { dg-do compile { target c++11 } }
+
+template <typename, typename, typename = void, typename...>
+struct foo {};  // { dg-message "provided for" }
+
+foo<int> f;     // { dg-error "at least 2" }
Index: testsuite/g++.dg/cpp0x/variadic2.C
===================================================================
--- testsuite/g++.dg/cpp0x/variadic2.C	(revision 213952)
+++ testsuite/g++.dg/cpp0x/variadic2.C	(working copy)
@@ -6,9 +6,9 @@  template<typename... = int> // { dg-error "default
 class tuple3;
 
 template<typename T1, typename T2, typename... Rest>
-struct two_or_more {}; // { dg-error "provided for" }
+struct two_or_more {}; // { dg-message "provided for" }
 
-typedef two_or_more<int> bad; // { dg-error "2 or more" "2 or more" }
+typedef two_or_more<int> bad; // { dg-error "at least 2" "at least 2" }
 
 void f()
 {
Index: testsuite/g++.dg/parse/too-many-tmpl-args1.C
===================================================================
--- testsuite/g++.dg/parse/too-many-tmpl-args1.C	(revision 213952)
+++ testsuite/g++.dg/parse/too-many-tmpl-args1.C	(working copy)
@@ -2,7 +2,7 @@ 
 // Origin: Wolfgang Bangerth <bangerth@ticam.utexas.edu>
 // { dg-do compile }
 
-template <typename T> class A                                 // { dg-error "" }
+template <typename T> class A                               // { dg-message "" }
 {
     struct B;
     template <typename U> friend typename A<U,void>::B foo(); // { dg-error "" }
Index: testsuite/g++.dg/template/dtor3.C
===================================================================
--- testsuite/g++.dg/template/dtor3.C	(revision 213952)
+++ testsuite/g++.dg/template/dtor3.C	(working copy)
@@ -1,4 +1,4 @@ 
 // PR c++/19762
 
-template<int> struct A { ~A(){} }; // { dg-error "" }
+template<int> struct A { ~A(){} }; // { dg-message "provided for" }
 template A<>::~A(); // { dg-error "template|declaration" }
Index: testsuite/g++.dg/template/pr54377.C
===================================================================
--- testsuite/g++.dg/template/pr54377.C	(revision 0)
+++ testsuite/g++.dg/template/pr54377.C	(working copy)
@@ -0,0 +1,6 @@ 
+// PR c++/54377
+
+template <typename, typename, typename = void, typename = void>
+struct foo {};  // { dg-message "provided for" }
+
+foo<int> f;     // { dg-error "at least 2" }
Index: testsuite/g++.dg/template/qualttp4.C
===================================================================
--- testsuite/g++.dg/template/qualttp4.C	(revision 213952)
+++ testsuite/g++.dg/template/qualttp4.C	(working copy)
@@ -7,7 +7,7 @@  struct A
 	template <class T> struct B {};
 };
 
-template <template <class, class> class TT> // { dg-error "provided" }
+template <template <class, class> class TT> // { dg-message "provided for" }
 struct X
 {
 	TT<int> y; // { dg-error "number" }
Index: testsuite/g++.dg/template/spec28.C
===================================================================
--- testsuite/g++.dg/template/spec28.C	(revision 213952)
+++ testsuite/g++.dg/template/spec28.C	(working copy)
@@ -2,5 +2,5 @@ 
 // Bad diagnostic
 // { dg-do compile }
 
-template<typename> struct A {};  // { dg-error "provided" }
+template<typename> struct A {};  // { dg-message "provided for" }
 template<> struct A<> {};        // { dg-error "wrong number" }
Index: testsuite/g++.old-deja/g++.brendan/crash8.C
===================================================================
--- testsuite/g++.old-deja/g++.brendan/crash8.C	(revision 213952)
+++ testsuite/g++.old-deja/g++.brendan/crash8.C	(working copy)
@@ -1,7 +1,7 @@ 
 // { dg-do compile }
 // GROUPS passed old-abort
 template<int a, int b>
-class Elvis // { dg-error "class Elvis" }
+class Elvis // { dg-message "class Elvis" }
 {
 } ;
 
Index: testsuite/g++.old-deja/g++.pt/ttp7.C
===================================================================
--- testsuite/g++.old-deja/g++.pt/ttp7.C	(revision 213952)
+++ testsuite/g++.old-deja/g++.pt/ttp7.C	(working copy)
@@ -4,7 +4,7 @@  template<class E> class D
 {
 };
 
-template<template<class> class D,class E> class C	// { dg-error "" } ref below
+template<template<class> class D,class E> class C	// { dg-message "" } ref below
 {
 	D<int,int> d;				// { dg-error "" } arg not match
 };