re PR c++/16829 (default parameter can be not one of the last in function)

PR c++/16829
	* decl.c (start_preparsed_function): Check default arguments
	unconditionally.
	* name-lookup.c (pushdecl_maybe_friend): Check default arguments
	of all functions and function templates.
	* parser.c (cp_parser_late_parsing_default_args): Check default
	arguments.
	* decl2.c (check_default_args): Set missing default arguments to
	error_mark_node.

	* g++.dg/other/default2.C: New test.
	* g++.dg/other/default3.C: New test.

From-SVN: r109950
This commit is contained in:
Volker Reichelt 2006-01-19 09:51:57 +00:00 committed by Volker Reichelt
parent 1f0f7cebf9
commit 607c855eb7
8 changed files with 145 additions and 8 deletions

View File

@ -1,3 +1,15 @@
2006-01-19 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
PR c++/16829
* decl.c (start_preparsed_function): Check default arguments
unconditionally.
* name-lookup.c (pushdecl_maybe_friend): Check default arguments
of all functions and function templates.
* parser.c (cp_parser_late_parsing_default_args): Check default
arguments.
* decl2.c (check_default_args): Set missing default arguments to
error_mark_node.
2006-01-18 Mark Mitchell <mark@codesourcery.com>
PR c++/25836

View File

@ -10217,6 +10217,8 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
you declare a function, these types can be incomplete, but they
must be complete when you define the function. */
check_function_type (decl1, current_function_parms);
/* Make sure no default arg is missing. */
check_default_args (decl1);
/* Build the return declaration for the function. */
restype = TREE_TYPE (fntype);
@ -10283,8 +10285,6 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
/* We need to set the DECL_CONTEXT. */
if (!DECL_CONTEXT (decl1) && DECL_TEMPLATE_INFO (decl1))
DECL_CONTEXT (decl1) = DECL_CONTEXT (DECL_TI_TEMPLATE (decl1));
/* And make sure we have enough default args. */
check_default_args (decl1);
}
fntype = TREE_TYPE (decl1);
}

View File

@ -3228,7 +3228,7 @@ check_default_args (tree x)
else if (saw_def)
{
error ("default argument missing for parameter %P of %q+#D", i, x);
break;
TREE_PURPOSE (arg) = error_mark_node;
}
}
}

View File

@ -602,6 +602,9 @@ pushdecl_maybe_friend (tree x, bool is_friend)
{
int different_binding_level = 0;
if (TREE_CODE (x) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (x))
check_default_args (x);
if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
name = TREE_OPERAND (name, 0);
@ -710,8 +713,6 @@ pushdecl_maybe_friend (tree x, bool is_friend)
{
if (TREE_CODE (t) == TYPE_DECL)
SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (t));
else if (TREE_CODE (t) == FUNCTION_DECL)
check_default_args (t);
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
}
@ -994,9 +995,6 @@ pushdecl_maybe_friend (tree x, bool is_friend)
}
}
if (TREE_CODE (x) == FUNCTION_DECL)
check_default_args (x);
if (TREE_CODE (x) == VAR_DECL)
maybe_register_incomplete_var (x);
}

View File

@ -15833,6 +15833,9 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
cp_parser_pop_lexer (parser);
}
/* Make sure no default arg is missing. */
check_default_args (fn);
/* Restore the state of local_variables_forbidden_p. */
parser->local_variables_forbidden_p = saved_local_variables_forbidden_p;

View File

@ -1,3 +1,9 @@
2006-01-19 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
PR c++/16829
* g++.dg/other/default2.C: New test.
* g++.dg/other/default3.C: New test.
2006-01-19 Richard Sandiford <richard@codesourcery.com>
PR c/25805

View File

@ -0,0 +1,9 @@
// PR c++/16829
// { dg-do "compile" }
template<typename T> void foo(T, int = 0, int) {} // { dg-error "default" }
void bar()
{
foo(0);
}

View File

@ -0,0 +1,109 @@
// PR c++/16829
// { dg-do "compile" }
void f1(int = 0, int); // { dg-error "default" }
void f2(int = 0, int) {} // { dg-error "default" }
void f3(int, int);
void f3(int = 0, int); // { dg-error "default" }
void f4(int, int);
void f4(int = 0, int) {} // { dg-error "default" }
void f5();
void f5(int = 0, int); // { dg-error "default" }
void f6();
void f6(int = 0, int) {} // { dg-error "default" }
template<typename> void g1(int = 0, int); // { dg-error "default" }
template<typename> void g2(int = 0, int) {} // { dg-error "default" }
template<typename> void g3(int, int);
template<typename> void g3(int = 0, int); // { dg-error "default" }
template<typename> void g4(int, int);
template<typename> void g4(int = 0, int) {} // { dg-error "default" }
template<typename> void g5();
template<typename> void g5(int = 0, int); // { dg-error "default" }
template<typename> void g6();
template<typename> void g6(int = 0, int) {} // { dg-error "default" }
template<typename T> void g7(T, T) {}
template<typename T> void g7(T* = 0, T*) {} // { dg-error "default" }
struct A
{
void F1(int = 0, int); // { dg-error "default" }
void F2(int = 0, int) {} // { dg-error "default" }
void F3(int, int);
void F4();
void F4(int = 0, int); // { dg-error "default" }
void F5();
void F5(int = 0, int) {} // { dg-error "default" }
template<typename> void G1(int = 0, int); // { dg-error "default" }
template<typename> void G2(int = 0, int) {} // { dg-error "default" }
template<typename> void G3(int, int);
template<typename> void G4();
template<typename> void G4(int = 0, int); // { dg-error "default" }
template<typename> void G5();
template<typename> void G5(int = 0, int) {} // { dg-error "default" }
template<typename T> void G6(T, T) {}
template<typename T> void G6(T* = 0, T*) {} // { dg-error "default" }
};
void A::F3(int = 0, int) {} // { dg-error "default" }
template<typename> void A::G3(int = 0, int) {} // { dg-error "default" }
template<typename> struct B
{
void F1(int = 0, int); // { dg-error "default" }
void F2(int = 0, int) {} // { dg-error "default" }
void F3(int, int);
void F4();
void F4(int = 0, int); // { dg-error "default" }
void F5();
void F5(int = 0, int) {} // { dg-error "default" }
template<typename> void G1(int = 0, int); // { dg-error "default" }
template<typename> void G2(int = 0, int) {} // { dg-error "default" }
template<typename> void G3(int, int);
template<typename> void G4();
template<typename> void G4(int = 0, int); // { dg-error "default" }
template<typename> void G5();
template<typename> void G5(int = 0, int) {} // { dg-error "default" }
template<typename T> void G6(T, T) {}
template<typename T> void G6(T* = 0, T*) {} // { dg-error "default" }
};
template<typename T>
void B<T>::F3(int = 0, int) {} // { dg-error "default" }
template<typename T> template<typename>
void B<T>::G3(int = 0, int) {} // { dg-error "default" }