diff options
author | Paolo Carlini <paolo@gcc.gnu.org> | 2014-08-02 19:41:32 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2014-08-02 19:41:32 +0000 |
commit | e83a4a2e4040d52b9c0ef052b8f49b5afbed60ac (patch) | |
tree | 6de5ef6aa4224298ce3181785830dadf37745af8 /gcc | |
parent | 91bc34a94d157c64f82477e8cd44d55494e7b1b7 (diff) | |
download | gcc-e83a4a2e4040d52b9c0ef052b8f49b5afbed60ac.zip gcc-e83a4a2e4040d52b9c0ef052b8f49b5afbed60ac.tar.gz gcc-e83a4a2e4040d52b9c0ef052b8f49b5afbed60ac.tar.bz2 |
re PR c++/15339 ([DR217] Adding default arguments to function templates in redeclarations should be forbidden)
/cp
2014-08-02 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/15339
* decl.c (check_redeclaration_no_default_args): New.
(duplicate_decls): Use it, handle default arguments
in redeclarations of function templates.
/testsuite
2014-08-02 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/15339
* g++.dg/other/default9.C: New.
* g++.dg/other/default10.C: Likewise.
* g++.dg/other/default3.C: Remove xfail.
From-SVN: r213519
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/decl.c | 62 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/other/default10.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/other/default3.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/other/default9.C | 18 |
6 files changed, 80 insertions, 22 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 193a9c2..9fdd4c7 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2014-08-02 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/15339 + * decl.c (check_redeclaration_no_default_args): New. + (duplicate_decls): Use it, handle default arguments + in redeclarations of function templates. + 2014-08-02 Trevor Saunders <tsaunders@mozilla.com> * optimize.c, semantics.c: Use hash_map instead of pointer_map. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 88152f0..d4dde61 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1236,6 +1236,27 @@ validate_constexpr_redeclaration (tree old_decl, tree new_decl) return true; } +/* DECL is a redeclaration of a function or function template. If + it does have default arguments issue a diagnostic. Note: this + function is used to enforce the requirements in C++11 8.3.6 about + no default arguments in redeclarations. */ + +static void +check_redeclaration_no_default_args (tree decl) +{ + gcc_assert (DECL_DECLARES_FUNCTION_P (decl)); + + for (tree t = FUNCTION_FIRST_USER_PARMTYPE (decl); + t && t != void_list_node; t = TREE_CHAIN (t)) + if (TREE_PURPOSE (t)) + { + permerror (input_location, + "redeclaration of %q#D may not have default " + "arguments", decl); + return; + } +} + #define GNU_INLINE_P(fn) (DECL_DECLARED_INLINE_P (fn) \ && lookup_attribute ("gnu_inline", \ DECL_ATTRIBUTES (fn))) @@ -1706,28 +1727,23 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) ; else if (TREE_CODE (olddecl) == FUNCTION_DECL) { - tree t1 = FUNCTION_FIRST_USER_PARMTYPE (olddecl); - tree t2 = FUNCTION_FIRST_USER_PARMTYPE (newdecl); - int i = 1; - - if (DECL_FUNCTION_MEMBER_P (newdecl) - && CLASSTYPE_TEMPLATE_INFO (CP_DECL_CONTEXT (newdecl))) - { - /* C++11 8.3.6/6. - Default arguments for a member function of a class template - shall be specified on the initial declaration of the member - function within the class template. */ - for (; t2 && t2 != void_list_node; t2 = TREE_CHAIN (t2)) - if (TREE_PURPOSE (t2)) - { - permerror (input_location, - "redeclaration of %q#D may not have default " - "arguments", newdecl); - break; - } - } + /* Note: free functions, as TEMPLATE_DECLs, are handled below. */ + if (DECL_FUNCTION_MEMBER_P (olddecl) + && (/* grokfndecl passes member function templates too + as FUNCTION_DECLs. */ + DECL_TEMPLATE_INFO (olddecl) + /* C++11 8.3.6/6. + Default arguments for a member function of a class + template shall be specified on the initial declaration + of the member function within the class template. */ + || CLASSTYPE_TEMPLATE_INFO (CP_DECL_CONTEXT (olddecl)))) + check_redeclaration_no_default_args (newdecl); else { + tree t1 = FUNCTION_FIRST_USER_PARMTYPE (olddecl); + tree t2 = FUNCTION_FIRST_USER_PARMTYPE (newdecl); + int i = 1; + for (; t1 && t1 != void_list_node; t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2), i++) if (TREE_PURPOSE (t1) && TREE_PURPOSE (t2)) @@ -1864,6 +1880,12 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) if (DECL_FUNCTION_TEMPLATE_P (newdecl)) { + /* Per C++11 8.3.6/4, default arguments cannot be added in later + declarations of a function template. */ + check_redeclaration_no_default_args (newdecl); + + check_default_args (newdecl); + if (GNU_INLINE_P (old_result) != GNU_INLINE_P (new_result) && DECL_INITIAL (new_result)) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index aab6097..68c4cf6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,4 +1,11 @@ -2014-08-01 Jan Hubicka <hubicka@ucw.cz> +2014-08-02 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/15339 + * g++.dg/other/default9.C: New. + * g++.dg/other/default10.C: Likewise. + * g++.dg/other/default3.C: Remove xfail. + +2014-08-02 Jan Hubicka <hubicka@ucw.cz> * g++.dg/warn/Wsuggest-final.C: New testcase. * g++.dg/ipa/devirt-34.C: Fix. diff --git a/gcc/testsuite/g++.dg/other/default10.C b/gcc/testsuite/g++.dg/other/default10.C new file mode 100644 index 0000000..1c9731e --- /dev/null +++ b/gcc/testsuite/g++.dg/other/default10.C @@ -0,0 +1,4 @@ +// PR c++/15339 + +template<typename> void g3(int, int); +template<typename> void g3(int = 0, int) { } // { dg-error "may not have default arguments|default argument missing" } diff --git a/gcc/testsuite/g++.dg/other/default3.C b/gcc/testsuite/g++.dg/other/default3.C index 42c1fe4..025d2c1 100644 --- a/gcc/testsuite/g++.dg/other/default3.C +++ b/gcc/testsuite/g++.dg/other/default3.C @@ -25,7 +25,7 @@ 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" "" { xfail *-*-* } } +template<typename> void g4(int = 0, int) {} // { dg-error "default" } template<typename> void g5(); template<typename> void g5(int = 0, int); // { dg-error "default" } diff --git a/gcc/testsuite/g++.dg/other/default9.C b/gcc/testsuite/g++.dg/other/default9.C new file mode 100644 index 0000000..62f0a79 --- /dev/null +++ b/gcc/testsuite/g++.dg/other/default9.C @@ -0,0 +1,18 @@ +// PR c++/15339 + +template<typename> void fun(int); +template<typename> void fun(int = 0); // { dg-error "default arguments" } + +class A +{ + template<typename> void fun(int); +}; + +template<typename> void A::fun(int = 0) { } // { dg-error "default arguments" } + +class B +{ + void fun(int); +}; + +void B::fun(int = 0) { } |