diff options
author | Volker Reichelt <reichelt@igpm.rwth-aachen.de> | 2006-01-19 09:51:57 +0000 |
---|---|---|
committer | Volker Reichelt <reichelt@gcc.gnu.org> | 2006-01-19 09:51:57 +0000 |
commit | 607c855eb7fbf6b876250fe3e580125e7bf438d6 (patch) | |
tree | b6b738bfc0105ccb758373d329ad2bae1de1c072 /gcc | |
parent | 1f0f7cebf9eccfa3c9bac5c2602a261c487c86d2 (diff) | |
download | gcc-607c855eb7fbf6b876250fe3e580125e7bf438d6.zip gcc-607c855eb7fbf6b876250fe3e580125e7bf438d6.tar.gz gcc-607c855eb7fbf6b876250fe3e580125e7bf438d6.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/cp/decl.c | 4 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 2 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 8 | ||||
-rw-r--r-- | gcc/cp/parser.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/other/default2.C | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/other/default3.C | 109 |
8 files changed, 145 insertions, 8 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b386ef4..981976f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 48e985c..ae0b7e8 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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); } diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 9408c8a..637ac8c 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -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; } } } diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 02fc272..4a2482f 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -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); } diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index ec4c2ea..d2b41e5 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ca243bc..5a5e470 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/g++.dg/other/default2.C b/gcc/testsuite/g++.dg/other/default2.C new file mode 100644 index 0000000..be0e5c3 --- /dev/null +++ b/gcc/testsuite/g++.dg/other/default2.C @@ -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); +} diff --git a/gcc/testsuite/g++.dg/other/default3.C b/gcc/testsuite/g++.dg/other/default3.C new file mode 100644 index 0000000..324ba71 --- /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<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" } |