Commit 607c855e by Volker Reichelt Committed by Volker Reichelt

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
parent 1f0f7ceb
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> 2006-01-18 Mark Mitchell <mark@codesourcery.com>
PR c++/25836 PR c++/25836
......
...@@ -10217,6 +10217,8 @@ start_preparsed_function (tree decl1, tree attrs, int flags) ...@@ -10217,6 +10217,8 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
you declare a function, these types can be incomplete, but they you declare a function, these types can be incomplete, but they
must be complete when you define the function. */ must be complete when you define the function. */
check_function_type (decl1, current_function_parms); 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. */ /* Build the return declaration for the function. */
restype = TREE_TYPE (fntype); restype = TREE_TYPE (fntype);
...@@ -10283,8 +10285,6 @@ start_preparsed_function (tree decl1, tree attrs, int flags) ...@@ -10283,8 +10285,6 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
/* We need to set the DECL_CONTEXT. */ /* We need to set the DECL_CONTEXT. */
if (!DECL_CONTEXT (decl1) && DECL_TEMPLATE_INFO (decl1)) if (!DECL_CONTEXT (decl1) && DECL_TEMPLATE_INFO (decl1))
DECL_CONTEXT (decl1) = DECL_CONTEXT (DECL_TI_TEMPLATE (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); fntype = TREE_TYPE (decl1);
} }
......
...@@ -3228,7 +3228,7 @@ check_default_args (tree x) ...@@ -3228,7 +3228,7 @@ check_default_args (tree x)
else if (saw_def) else if (saw_def)
{ {
error ("default argument missing for parameter %P of %q+#D", i, x); error ("default argument missing for parameter %P of %q+#D", i, x);
break; TREE_PURPOSE (arg) = error_mark_node;
} }
} }
} }
......
...@@ -602,6 +602,9 @@ pushdecl_maybe_friend (tree x, bool is_friend) ...@@ -602,6 +602,9 @@ pushdecl_maybe_friend (tree x, bool is_friend)
{ {
int different_binding_level = 0; 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) if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
name = TREE_OPERAND (name, 0); name = TREE_OPERAND (name, 0);
...@@ -710,8 +713,6 @@ pushdecl_maybe_friend (tree x, bool is_friend) ...@@ -710,8 +713,6 @@ pushdecl_maybe_friend (tree x, bool is_friend)
{ {
if (TREE_CODE (t) == TYPE_DECL) if (TREE_CODE (t) == TYPE_DECL)
SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (t)); 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); POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
} }
...@@ -994,9 +995,6 @@ pushdecl_maybe_friend (tree x, bool is_friend) ...@@ -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) if (TREE_CODE (x) == VAR_DECL)
maybe_register_incomplete_var (x); maybe_register_incomplete_var (x);
} }
......
...@@ -15833,6 +15833,9 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn) ...@@ -15833,6 +15833,9 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
cp_parser_pop_lexer (parser); cp_parser_pop_lexer (parser);
} }
/* Make sure no default arg is missing. */
check_default_args (fn);
/* Restore the state of local_variables_forbidden_p. */ /* Restore the state of local_variables_forbidden_p. */
parser->local_variables_forbidden_p = saved_local_variables_forbidden_p; parser->local_variables_forbidden_p = saved_local_variables_forbidden_p;
......
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> 2006-01-19 Richard Sandiford <richard@codesourcery.com>
PR c/25805 PR c/25805
// PR c++/16829
// { dg-do "compile" }
template<typename T> void foo(T, int = 0, int) {} // { dg-error "default" }
void bar()
{
foo(0);
}
// 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" }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment