This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PR c++/34758 Bad diagnostic for circular dependency in constructor default argument
- From: Manuel López-Ibáñez <lopezibanez at gmail dot com>
- To: Gcc Patch List <gcc-patches at gcc dot gnu dot org>
- Cc: Paolo Carlini <paolo dot carlini at oracle dot com>, Mark Mitchell <mark at codesourcery dot com>, reichelt at gcc dot gnu dot org
- Date: Fri, 6 Feb 2009 22:17:44 +0100
- Subject: Re: PR c++/34758 Bad diagnostic for circular dependency in constructor default argument
- References: <6c33472e0808222111t52ce1c2fqb0a0ebfd266b045@mail.gmail.com> <6c33472e0810210844h783c4267ubeb9a4d51a7a7e31@mail.gmail.com>
I have updated the patch to a recent revision, bootstrapped and
regression tested again.
This is a P4 regression.
OK for trunk?
Manuel.
2008/10/21 Manuel López-Ibáñez <lopezibanez@gmail.com>:
> 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 143971)
+++ gcc/cp/typeck.c (working copy)
@@ -3108,11 +3108,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 143971)
+++ gcc/cp/call.c (working copy)
@@ -4921,28 +4921,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)
@@ -5284,11 +5288,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 143971)
+++ gcc/cp/cp-tree.h (working copy)
@@ -4193,11 +4193,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 143971)
+++ gcc/cp/cp-gimplify.c (working copy)
@@ -959,11 +959,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);
@@ -994,11 +996,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);
}
}