From: Volker Reichelt Date: Thu, 3 Aug 2006 02:41:33 +0000 (+0000) Subject: re PR c++/28274 (Redeclaration with extra default argument doesn't work) X-Git-Tag: releases/gcc-4.0.4~477 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9e50b12a1e094264fd577aada083f1bbf447e7d0;p=thirdparty%2Fgcc.git re PR c++/28274 (Redeclaration with extra default argument doesn't work) PR c++/28274 * decl.c (duplicate_decls): Call check_default_args here. (start_preparsed_function): Do not call check_default_args. * name-lookup.c (pushdecl_maybe_friend): Only call check_default_args if duplicate_decls got bypassed. * g++.dg/other/default5.C: New test. From-SVN: r115895 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9cc14806724d..29c59982fc84 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2006-08-03 Volker Reichelt + + PR c++/28274 + * decl.c (duplicate_decls): Call check_default_args here. + (start_preparsed_function): Do not call check_default_args. + * name-lookup.c (pushdecl_maybe_friend): Only call + check_default_args if duplicate_decls got bypassed. + 2006-07-24 Volker Reichelt PR c++/27572 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index a9d82142ffd5..63b491c684b5 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1573,6 +1573,9 @@ duplicate_decls (tree newdecl, tree olddecl) } TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = newtype; + if (TREE_CODE (newdecl) == FUNCTION_DECL) + check_default_args (newdecl); + /* Lay the type out, unless already done. */ if (! same_type_p (newtype, oldtype) && TREE_TYPE (newdecl) != error_mark_node @@ -10009,8 +10012,6 @@ 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); diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 2f1d39ec5c09..849144412069 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -601,9 +601,6 @@ 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); @@ -732,6 +729,9 @@ pushdecl (tree x) } } + if (TREE_CODE (x) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (x)) + check_default_args (x); + check_template_shadow (x); /* If this is a function conjured up by the backend, massage it diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9a809b68009a..e5c632593656 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-08-03 Volker Reichelt + + PR c++/28274 + * g++.dg/other/default5.C: New test. + 2006-07-30 Roger Sayle PR middle-end/28473 diff --git a/gcc/testsuite/g++.dg/other/default5.C b/gcc/testsuite/g++.dg/other/default5.C new file mode 100644 index 000000000000..ad7eb01298cf --- /dev/null +++ b/gcc/testsuite/g++.dg/other/default5.C @@ -0,0 +1,47 @@ +// PR c++/28274 +// { dg-do "compile" } + +void f1(int, int, int, int, int = 0); +void f1(int, int, int, int = 0, int); +void f1(int, int, int = 0, int, int); +void f1(int = 0, int, int, int, int); // { dg-error "default" } + +void f2(int, int, int, int, int = 0) {} +void f2(int, int, int, int = 0, int); +void f2(int, int, int = 0, int, int); +void f2(int = 0, int, int, int, int); // { dg-error "default" } + +void f3(int, int, int, int, int = 0); +void f3(int, int, int, int = 0, int) {} +void f3(int, int, int = 0, int, int); +void f3(int = 0, int, int, int, int); // { dg-error "default" } + +void f4(int, int, int, int, int = 0); +void f4(int, int, int, int = 0, int); +void f4(int, int, int = 0, int, int) {} +void f4(int = 0, int, int, int, int); // { dg-error "default" } + +void f5(int, int, int, int, int = 0); +void f5(int, int, int, int = 0, int); +void f5(int, int, int = 0, int, int); +void f5(int = 0, int, int, int, int) {} // { dg-error "default" } + + +struct A +{ + void F1(int, int, int = 0); + void F2(int, int, int = 0); +}; + +void A::F1(int, int = 0, int) {} +void A::F2(int = 0, int, int) {} // { dg-error "default" } + + +template struct B +{ + void F1(int, int, int = 0); + void F2(int, int, int = 0); +}; + +template void B::F1(int, int = 0, int) {} +template void B::F2(int = 0, int, int) {} // { dg-error "default" }