re PR c++/34758 (Bad diagnostic for circular dependency in constructor default argument)
PR c++/34758 * call.c (convert_default_arg): Use DECL_ORIGIN of fn. Check for recursion first. (push_defarg_context, pop_defarg_context): New. * parser.c (cp_parser_late_parsing_default_args): Use them. * cp-tree.h: Declare them. From-SVN: r171009
This commit is contained in:
parent
56b6751058
commit
4c66d85a55
|
@ -1,3 +1,12 @@
|
|||
2011-03-15 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/34758
|
||||
* call.c (convert_default_arg): Use DECL_ORIGIN of fn. Check for
|
||||
recursion first.
|
||||
(push_defarg_context, pop_defarg_context): New.
|
||||
* parser.c (cp_parser_late_parsing_default_args): Use them.
|
||||
* cp-tree.h: Declare them.
|
||||
|
||||
2011-03-11 Dodji Seketeli <dodji@redhat.com>
|
||||
|
||||
* call.c (add_builtin_candidate)<case INDIRECT_REF>: The type of
|
||||
|
|
|
@ -5746,10 +5746,17 @@ cxx_type_promotes_to (tree type)
|
|||
}
|
||||
|
||||
/* 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;
|
||||
void
|
||||
push_defarg_context (tree fn)
|
||||
{ VEC_safe_push (tree, gc, default_arg_context, fn); }
|
||||
void
|
||||
pop_defarg_context (void)
|
||||
{ VEC_pop (tree, default_arg_context); }
|
||||
|
||||
tree
|
||||
convert_default_arg (tree type, tree arg, tree fn, int parmnum)
|
||||
|
@ -5757,15 +5764,8 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum)
|
|||
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);
|
||||
return error_mark_node;
|
||||
}
|
||||
/* See through clones. */
|
||||
fn = DECL_ORIGIN (fn);
|
||||
|
||||
/* Detect recursion. */
|
||||
FOR_EACH_VEC_ELT (tree, default_arg_context, i, t)
|
||||
|
@ -5774,7 +5774,17 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum)
|
|||
error ("recursive evaluation of default argument for %q#D", fn);
|
||||
return error_mark_node;
|
||||
}
|
||||
VEC_safe_push (tree, gc, default_arg_context, fn);
|
||||
|
||||
/* If the ARG is an unparsed default argument expression, the
|
||||
conversion cannot be performed. */
|
||||
if (TREE_CODE (arg) == DEFAULT_ARG)
|
||||
{
|
||||
error ("call to %qD uses the default argument for parameter %P, which "
|
||||
"is not yet defined", fn, parmnum);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
push_defarg_context (fn);
|
||||
|
||||
if (fn && DECL_TEMPLATE_INFO (fn))
|
||||
arg = tsubst_default_argument (fn, type, arg);
|
||||
|
@ -5814,7 +5824,7 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum)
|
|||
}
|
||||
pop_deferring_access_checks();
|
||||
|
||||
VEC_pop (tree, default_arg_context);
|
||||
pop_defarg_context ();
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
|
|
@ -4638,6 +4638,8 @@ extern bool can_convert (tree, tree);
|
|||
extern bool can_convert_arg (tree, tree, tree, int);
|
||||
extern bool can_convert_arg_bad (tree, tree, tree, int);
|
||||
extern bool enforce_access (tree, tree, tree);
|
||||
extern void push_defarg_context (tree);
|
||||
extern void pop_defarg_context (void);
|
||||
extern tree convert_default_arg (tree, tree, tree, int);
|
||||
extern tree convert_arg_to_ellipsis (tree);
|
||||
extern tree build_x_va_arg (tree, tree);
|
||||
|
|
|
@ -20521,6 +20521,8 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
|
|||
saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
|
||||
parser->local_variables_forbidden_p = true;
|
||||
|
||||
push_defarg_context (fn);
|
||||
|
||||
for (parm = TYPE_ARG_TYPES (TREE_TYPE (fn)),
|
||||
parmdecl = DECL_ARGUMENTS (fn);
|
||||
parm && parm != void_list_node;
|
||||
|
@ -20579,6 +20581,8 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
|
|||
cp_parser_pop_lexer (parser);
|
||||
}
|
||||
|
||||
pop_defarg_context ();
|
||||
|
||||
/* Make sure no default arg is missing. */
|
||||
check_default_args (fn);
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2011-03-15 Manuel López-Ibáñez <manu@gcc.gnu.org>
|
||||
|
||||
* g++.dg/parse/pr34758.C: New.
|
||||
|
||||
2011-03-15 Xinliang David Li <davidxl@google.com>
|
||||
|
||||
PR c/47837
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
// PR 34758 Bad diagnostic for circular dependency in constructor default argument
|
||||
// { dg-do compile }
|
||||
// { dg-options "" }
|
||||
struct A
|
||||
{
|
||||
A (const A& = A()); // { dg-error "recursive evaluation of default argument" }
|
||||
};
|
||||
|
||||
|
||||
struct S {
|
||||
S(const S& = f()); // { dg-error "default argument\[^\n\]*which is not yet defined" }
|
||||
static const S& f(int i = 3);
|
||||
};
|
||||
|
||||
struct J {
|
||||
J(const J& = f(2)); // { dg-error "default argument.*which is not yet defined" }
|
||||
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);
|
||||
};
|
Loading…
Reference in New Issue