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) { }

Reply via email to