From: Volker Reichelt Date: Tue, 24 Jan 2006 11:38:06 +0000 (+0000) Subject: re PR c++/16829 (default parameter can be not one of the last in function) X-Git-Tag: releases/gcc-3.4.6~131 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3ac473fdf27bd8864870b5cc2ff3897c84b83841;p=thirdparty%2Fgcc.git 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: r110167 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2d5c6b106fd2..9c032d50aa46 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2006-01-24 Volker Reichelt + + 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-19 Volker Reichelt PR c++/25854 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 5adb3a8d3f0c..74a386d941db 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -10330,6 +10330,8 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags) must be complete when you define the function. */ if (! processing_template_decl) 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); @@ -10393,8 +10395,6 @@ start_function (tree declspecs, tree declarator, 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); } diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 0a7155ed470f..55d68a2e6016 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2959,7 +2959,7 @@ check_default_args (tree x) { cp_error_at ("default argument missing for parameter %P of `%+#D'", i, x); - break; + TREE_PURPOSE (arg) = error_mark_node; } } } diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 28d89e93fb20..870eaabe120b 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -606,6 +606,9 @@ pushdecl (tree x) { 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); @@ -717,8 +720,6 @@ pushdecl (tree x) { 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); } @@ -1001,9 +1002,6 @@ pushdecl (tree x) } } - if (TREE_CODE (x) == FUNCTION_DECL) - check_default_args (x); - if (TREE_CODE (x) == VAR_DECL) maybe_register_incomplete_var (x); } diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 24b802b33fa8..032cbd7e9b76 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -14929,6 +14929,9 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn) parser->local_variables_forbidden_p = saved_local_variables_forbidden_p; } + /* Make sure no default arg is missing. */ + check_default_args (fn); + /* Restore the queue. */ parser->unparsed_functions_queues = TREE_CHAIN (parser->unparsed_functions_queues); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1e2995be7f8f..fa16199483fe 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2006-01-24 Volker Reichelt + + PR c++/16829 + * g++.dg/other/default2.C: New test. + * g++.dg/other/default3.C: New test. + 2006-01-19 Volker Reichelt PR c++/25854 diff --git a/gcc/testsuite/g++.dg/other/default2.C b/gcc/testsuite/g++.dg/other/default2.C new file mode 100644 index 000000000000..be0e5c32413d --- /dev/null +++ b/gcc/testsuite/g++.dg/other/default2.C @@ -0,0 +1,9 @@ +// PR c++/16829 +// { dg-do "compile" } + +template void foo(T, int = 0, int) {} // { dg-error "default" } + +void bar() +{ + foo(0); +} diff --git a/gcc/testsuite/g++.dg/other/default3.C b/gcc/testsuite/g++.dg/other/default3.C new file mode 100644 index 000000000000..324ba7146fe1 --- /dev/null +++ b/gcc/testsuite/g++.dg/other/default3.C @@ -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 void g1(int = 0, int); // { dg-error "default" } + +template void g2(int = 0, int) {} // { dg-error "default" } + +template void g3(int, int); +template void g3(int = 0, int); // { dg-error "default" } + +template void g4(int, int); +template void g4(int = 0, int) {} // { dg-error "default" } + +template void g5(); +template void g5(int = 0, int); // { dg-error "default" } + +template void g6(); +template void g6(int = 0, int) {} // { dg-error "default" } + +template void g7(T, T) {} +template 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 void G1(int = 0, int); // { dg-error "default" } + + template void G2(int = 0, int) {} // { dg-error "default" } + + template void G3(int, int); + + template void G4(); + template void G4(int = 0, int); // { dg-error "default" } + + template void G5(); + template void G5(int = 0, int) {} // { dg-error "default" } + + template void G6(T, T) {} + template void G6(T* = 0, T*) {} // { dg-error "default" } +}; + +void A::F3(int = 0, int) {} // { dg-error "default" } + +template void A::G3(int = 0, int) {} // { dg-error "default" } + + +template 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 void G1(int = 0, int); // { dg-error "default" } + + template void G2(int = 0, int) {} // { dg-error "default" } + + template void G3(int, int); + + template void G4(); + template void G4(int = 0, int); // { dg-error "default" } + + template void G5(); + template void G5(int = 0, int) {} // { dg-error "default" } + + template void G6(T, T) {} + template void G6(T* = 0, T*) {} // { dg-error "default" } +}; + +template +void B::F3(int = 0, int) {} // { dg-error "default" } + +template template +void B::G3(int = 0, int) {} // { dg-error "default" }