From 97d12d29aaf0502b243d7a39dc22bd7a8074b039 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Mon, 25 Nov 2013 22:24:58 +0000 Subject: [PATCH] re PR c++/54485 (g++ should diagnose default arguments in out-of-line definitions for template class member functions) /cp 2013-11-25 Paolo Carlini PR c++/54485 * decl.c (duplicate_decls): Enforce 8.3.6/6 about default arguments for member functions of class templates. /testsuite 2013-11-25 Paolo Carlini PR c++/54485 * g++.dg/other/default8.C: New. * g++.dg/tc1/dr217.C: Remove xfail. * g++.dg/other/default5.C: Adjust. * g++.old-deja/g++.mike/p1989.C: Likewise. From-SVN: r205367 --- gcc/cp/ChangeLog | 6 +++ gcc/cp/decl.c | 52 +++++++++++++++------ gcc/testsuite/ChangeLog | 8 ++++ gcc/testsuite/g++.dg/other/default5.C | 4 +- gcc/testsuite/g++.dg/other/default8.C | 43 +++++++++++++++++ gcc/testsuite/g++.dg/tc1/dr217.C | 2 +- gcc/testsuite/g++.old-deja/g++.mike/p1989.C | 2 +- 7 files changed, 98 insertions(+), 19 deletions(-) create mode 100644 gcc/testsuite/g++.dg/other/default8.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e567aa0c9da6..64f9a23632db 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2013-11-25 Paolo Carlini + + PR c++/54485 + * decl.c (duplicate_decls): Enforce 8.3.6/6 about default arguments + for member functions of class templates. + 2013-11-25 Paolo Carlini PR c++/58607 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 75e29f4bfa22..bf4d8e3d6846 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1704,25 +1704,47 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) if (TREE_CODE (TREE_TYPE (newdecl)) == METHOD_TYPE) t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2); - for (; t1 && t1 != void_list_node; - t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2), i++) - if (TREE_PURPOSE (t1) && TREE_PURPOSE (t2)) - { - if (1 == simple_cst_equal (TREE_PURPOSE (t1), - TREE_PURPOSE (t2))) + if (TREE_CODE (TREE_TYPE (newdecl)) == METHOD_TYPE + && 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, "default argument given for parameter %d of %q#D", - i, newdecl); - permerror (input_location, "after previous specification in %q+#D", olddecl); + permerror (input_location, + "redeclaration of %q#D may not have default " + "arguments", newdecl); + break; } - else + } + else + { + for (; t1 && t1 != void_list_node; + t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2), i++) + if (TREE_PURPOSE (t1) && TREE_PURPOSE (t2)) { - error ("default argument given for parameter %d of %q#D", - i, newdecl); - error ("after previous specification in %q+#D", - olddecl); + if (1 == simple_cst_equal (TREE_PURPOSE (t1), + TREE_PURPOSE (t2))) + { + permerror (input_location, + "default argument given for parameter %d " + "of %q#D", i, newdecl); + permerror (input_location, + "after previous specification in %q+#D", + olddecl); + } + else + { + error ("default argument given for parameter %d " + "of %q#D", i, newdecl); + error ("after previous specification in %q+#D", + olddecl); + } } - } + } } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 920f8268c352..2e9ff158fb28 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2013-11-25 Paolo Carlini + + PR c++/54485 + * g++.dg/other/default8.C: New. + * g++.dg/tc1/dr217.C: Remove xfail. + * g++.dg/other/default5.C: Adjust. + * g++.old-deja/g++.mike/p1989.C: Likewise. + 2013-11-25 Paolo Carlini PR c++/58607 diff --git a/gcc/testsuite/g++.dg/other/default5.C b/gcc/testsuite/g++.dg/other/default5.C index d5bae344c447..87acb765e6d6 100644 --- a/gcc/testsuite/g++.dg/other/default5.C +++ b/gcc/testsuite/g++.dg/other/default5.C @@ -43,5 +43,5 @@ template struct B 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" } +template void B::F1(int, int = 0, int) {} // { dg-error "default arguments" } +template void B::F2(int = 0, int, int) {} // { dg-error "default arguments|parameter 2" } diff --git a/gcc/testsuite/g++.dg/other/default8.C b/gcc/testsuite/g++.dg/other/default8.C new file mode 100644 index 000000000000..255a661356c5 --- /dev/null +++ b/gcc/testsuite/g++.dg/other/default8.C @@ -0,0 +1,43 @@ +// PR c++54485 + +template +class K1 +{ + int fn(int, int); + int gn(int, int); +}; + +template +int K1::fn (int a, int b = 3) // { dg-error "default arguments" } +{ + return a - b; +} + +template +int K1::gn (int a = 1, int b = 3) // { dg-error "default arguments" } +{ + return a - b; +} + +template +class K2 +{ + template + int fn(int, int); + template + int gn(int, int); +}; + +template +template +int K2::fn (int a, int b = 3) // { dg-error "default arguments" } +{ + return a - b; +} + +template +template +int K2::gn (int a = 1, int b = 3) // { dg-error "default arguments" } +{ + return a - b; +} diff --git a/gcc/testsuite/g++.dg/tc1/dr217.C b/gcc/testsuite/g++.dg/tc1/dr217.C index cfa2803974d6..099359b216a7 100644 --- a/gcc/testsuite/g++.dg/tc1/dr217.C +++ b/gcc/testsuite/g++.dg/tc1/dr217.C @@ -10,5 +10,5 @@ struct S }; template -void S::foo (int = 0) // { dg-error "" "default arguments for parameters of member functions of class templates can be specified in the initial declaration only" { xfail *-*-* } } +void S::foo (int = 0) // { dg-error "" "default arguments for parameters of member functions of class templates can be specified in the initial declaration only" } { } diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p1989.C b/gcc/testsuite/g++.old-deja/g++.mike/p1989.C index 487f609a1451..fdede63e406e 100644 --- a/gcc/testsuite/g++.old-deja/g++.mike/p1989.C +++ b/gcc/testsuite/g++.old-deja/g++.mike/p1989.C @@ -108,7 +108,7 @@ List_DL::prepend(const T& item) template void -List_DL::insert(const T& item, Pix x, bool before = TRUE) +List_DL::insert(const T& item, Pix x, bool before = TRUE) // { dg-error "default arguments" } { link *l = (link *) x; -- 2.47.3