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]

Re: PR c++/34758 Bad diagnostic for circular dependency in constructor default argument


I updated the patch to a recent revision, bootstrapped and regression
tested again.

OK for trunk?

Manuel.

2008/8/23 Manuel López-Ibáñez <lopezibanez@gmail.com>:
> Bootstrapped and regression tested on x86_64-unknown-linux-gnu with
> --enable-languages=all,ada
>
> Is the wording clear now?
>
> OK for trunk?
>
> 2008-08-18  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
>
>        PR c++/34758
> cp/
>        * call.c (convert_default_argument): Take an additional last_arg
>        argument. Clarify error message.
>        (build_over_call): Update call to convert_default_arg.
>        * typeck.c (convert_arguments): Update call to
>        convert_default_arg.
>        * cp-tree.h (convert_default_arg): Update declaration.
>        * cp-gimplify.c (cxx_omp_clause_apply_fn): Update call to
>        convert_default_arg.
> testsuite/
>        * g++.dg/parse/pr34758.C: New.
>
Index: gcc/testsuite/g++.dg/parse/pr34758.C
===================================================================
--- gcc/testsuite/g++.dg/parse/pr34758.C	(revision 0)
+++ gcc/testsuite/g++.dg/parse/pr34758.C	(revision 0)
@@ -0,0 +1,29 @@
+// PR 34758 Bad diagnostic for circular dependency in constructor default argument
+// { dg-do compile }
+// { dg-options "" }
+struct A
+{
+  A (const A& = A()); // { dg-error "'\[^\n\]*A::A\[^\n\]*' needs to be declared before called with default argument" }
+};
+
+
+struct S {
+  S(const S& = f()); // { dg-error "'\[^\n\]*S::f\[^\n\]*' needs to be declared before called with default argument" }
+  static const S& f(int i = 3);
+};
+
+struct J {
+  J(const J& = f(2)); // { dg-error "'\[^\n\]*J::f\[^\n\]*' needs to be declared before called with a default argument for parameter 2" }
+  static const J& f(int i = 3, int j = 4);
+};
+
+struct Z {
+  Z(const Z& = f(4));
+  static const Z& f(int i = 3);
+};
+
+struct X {
+  X(const X& = g());
+  static const X& g(void);
+};
+
Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c	(revision 141240)
+++ gcc/cp/typeck.c	(working copy)
@@ -3076,11 +3076,13 @@ convert_arguments (int nargs, tree *arga
 	  for (; typetail != void_list_node; ++i)
 	    {
 	      tree parmval
 		= convert_default_arg (TREE_VALUE (typetail),
 				       TREE_PURPOSE (typetail),
-				       fndecl, i);
+				       fndecl, i,
+				       /* last_arg = */
+				       TREE_CHAIN (typetail) == void_list_node);
 
 	      if (parmval == error_mark_node)
 		return -1;
 
 	      argarray[i] = parmval;
Index: gcc/cp/call.c
===================================================================
--- gcc/cp/call.c	(revision 141240)
+++ gcc/cp/call.c	(working copy)
@@ -4909,28 +4909,32 @@ cxx_type_promotes_to (tree type)
 
   return promote;
 }
 
 /* ARG is a default argument expression being passed to a parameter of
-   the indicated TYPE, which is a parameter to FN.  Do any required
-   conversions.  Return the converted value.  */
+   the indicated TYPE, which is a parameter to FN.  LAST_ARG is true
+   if this is the last argument. Do any required conversions.  Return
+   the converted value.  */
 
 static GTY(()) VEC(tree,gc) *default_arg_context;
 
 tree
-convert_default_arg (tree type, tree arg, tree fn, int parmnum)
+convert_default_arg (tree type, tree arg, tree fn, int parmnum, bool last_arg)
 {
   int i;
   tree t;
 
   /* If the ARG is an unparsed default argument expression, the
      conversion cannot be performed.  */
   if (TREE_CODE (arg) == DEFAULT_ARG)
     {
-      error ("the default argument for parameter %d of %qD has "
-	     "not yet been parsed",
-	     parmnum, fn);
+      if (parmnum != 0 || !last_arg) 
+	error ("%qD needs to be declared before called with a default argument "
+	       "for parameter %d", fn, parmnum + 1);
+      else
+	error ("%qD needs to be declared before called with default argument",
+	       fn);
       return error_mark_node;
     }
 
   /* Detect recursion.  */
   for (i = 0; VEC_iterate (tree, default_arg_context, i, t); ++i)
@@ -5262,11 +5266,12 @@ build_over_call (struct z_candidate *can
 
   /* Default arguments */
   for (; parm && parm != void_list_node; parm = TREE_CHAIN (parm), i++)
     argarray[j++] = convert_default_arg (TREE_VALUE (parm),
 					 TREE_PURPOSE (parm),
-					 fn, i - is_method);
+					 fn, i - is_method, /*last_arg=*/
+					 TREE_CHAIN (parm) == void_list_node);
   /* Ellipsis */
   for (; arg; arg = TREE_CHAIN (arg))
     {
       tree a = TREE_VALUE (arg);
       if (magic_varargs_p (fn))
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h	(revision 141240)
+++ gcc/cp/cp-tree.h	(working copy)
@@ -4186,11 +4186,11 @@ extern tree build_new_op			(enum tree_co
 extern tree build_op_delete_call		(enum tree_code, tree, tree, bool, tree, tree);
 extern bool can_convert				(tree, tree);
 extern bool can_convert_arg			(tree, tree, tree, int);
 extern bool can_convert_arg_bad			(tree, tree, tree);
 extern bool enforce_access			(tree, tree, tree);
-extern tree convert_default_arg			(tree, tree, tree, int);
+extern tree convert_default_arg			(tree, tree, tree, int, bool);
 extern tree convert_arg_to_ellipsis		(tree);
 extern tree build_x_va_arg			(tree, tree);
 extern tree cxx_type_promotes_to		(tree);
 extern tree type_passed_as			(tree);
 extern tree convert_for_arg_passing		(tree, tree);
Index: gcc/cp/cp-gimplify.c
===================================================================
--- gcc/cp/cp-gimplify.c	(revision 141240)
+++ gcc/cp/cp-gimplify.c	(working copy)
@@ -957,11 +957,13 @@ cxx_omp_clause_apply_fn (tree fn, tree a
 	argarray[i++] = p2;
       /* Handle default arguments.  */
       for (parm = defparm; parm && parm != void_list_node;
 	   parm = TREE_CHAIN (parm), i++)
 	argarray[i] = convert_default_arg (TREE_VALUE (parm),
-					   TREE_PURPOSE (parm), fn, i);
+					   TREE_PURPOSE (parm), fn, i,
+					   /* last_arg=*/
+					   TREE_CHAIN (parm) == void_list_node);
       t = build_call_a (fn, i, argarray);
       t = fold_convert (void_type_node, t);
       t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
       append_to_statement_list (t, &ret);
 
@@ -992,11 +994,13 @@ cxx_omp_clause_apply_fn (tree fn, tree a
       /* Handle default arguments.  */
       for (parm = defparm; parm && parm != void_list_node;
 	   parm = TREE_CHAIN (parm), i++)
 	argarray[i] = convert_default_arg (TREE_VALUE (parm),
 					   TREE_PURPOSE (parm),
-					   fn, i);
+					   fn, i,
+					   /* last_arg = */
+					   TREE_CHAIN (parm) == void_list_node);
       t = build_call_a (fn, i, argarray);
       t = fold_convert (void_type_node, t);
       return fold_build_cleanup_point_expr (TREE_TYPE (t), t);
     }
 }

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