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
Bootstrapped and regression tested on x86_64-unknown-linux-gnu with
--enable-languages=all,ada
OK for trunk?
2009-02-11 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
PR c++/34758
cp/
* call.c (convert_default_argument): Clarify error message.
testsuite/
* g++.dg/parse/pr34758.C: New.
2009/2/9 Mark Mitchell <mark@codesourcery.com>:
> Manuel López-Ibáñez wrote:
>
>>> Why is it worth having two messages? The people reading the messages
>>> are programmers; they'll understand that saying "argument 1" for a
>>> 1-argument function is just a computer being a bit redundant.
>>
>> I do not have the particular mail discussion at hand, but this was
>> explicitly requested there. I think it is nice, and I already took
>> that trouble to implement it. But if it is such a problem, then I
>> guess it can be de-implemented.
>
> I think it's overkill.
>
>> I do not see that convert_for_initialization documents parmnum
>> anywhere. The 0-based was already there, I haven't changed it.
>>
>> BTW, convert_for_initialization uses %P to print parmnum, whereas the
>> original code in convert_default_arg is using %d, so that may be the
>> reason why it does not use parmnum+1.
>
> OK, so then lets use %P in both places.
>
> Thanks,
>
> --
> Mark Mitchell
> CodeSourcery
> mark@codesourcery.com
> (650) 331-3385 x713
>
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 a default argument" }
+};
+
+
+struct S {
+ S(const S& = f()); // { dg-error "'\[^\n\]*S::f\[^\n\]*' needs to be declared before called with a 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/call.c
===================================================================
--- gcc/cp/call.c (revision 143971)
+++ gcc/cp/call.c (working copy)
@@ -4921,12 +4921,13 @@ 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. PARMNUM is the
+ zero-based argument number. 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)
@@ -4936,13 +4937,12 @@ convert_default_arg (tree type, tree arg
/* 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);
+ error ("%qD needs to be declared before called with a default argument "
+ "for parameter %P", fn, parmnum);
return error_mark_node;
}
/* Detect recursion. */
for (i = 0; VEC_iterate (tree, default_arg_context, i, t); ++i)