Hi,
thus this is what I have tested for c++/15339. By the way, I figured out
why yesterday I got stupidly confused about DECL_TEMPLATE_INFO: at this
point, for a member function template, newdecl does *not* have
DECL_TEMPLATE_INFO set, only olddecl does. Consistently, I adjusted all
the code in the condition to work on olddecl. Tested x86_64-linux.
Thanks,
Paolo.
//////////////////
/cp
2014-08-01 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/15339
* decl.c (duplicate_decls): Handle default arguments in function
templates.
/testsuite
2014-08-01 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/15339
* g++.dg/other/default9.C: New.
* g++.dg/other/default3.C: Remove xfail.
Index: cp/decl.c
===================================================================
--- cp/decl.c (revision 213505)
+++ cp/decl.c (working copy)
@@ -1704,19 +1704,23 @@ duplicate_decls (tree newdecl, tree olddecl, bool
if (DECL_LANG_SPECIFIC (olddecl) && DECL_USE_TEMPLATE (olddecl))
;
- else if (TREE_CODE (olddecl) == FUNCTION_DECL)
+ else if (DECL_DECLARES_FUNCTION_P (olddecl))
{
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)))
+ if (DECL_FUNCTION_TEMPLATE_P (olddecl)
+ || (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)))))
{
- /* 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))
{
Index: testsuite/g++.dg/other/default3.C
===================================================================
--- testsuite/g++.dg/other/default3.C (revision 213504)
+++ testsuite/g++.dg/other/default3.C (working copy)
@@ -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" }
Index: testsuite/g++.dg/other/default9.C
===================================================================
--- testsuite/g++.dg/other/default9.C (revision 0)
+++ testsuite/g++.dg/other/default9.C (working copy)
@@ -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) { }