Hi,

this bug, filed by Diego, is about 8.3.6/6, where member functions of class templates, at variance with plain classes, do not admit default arguments on the out-of-class redeclaration.

Tested x86_64-linux.

Thanks,
Paolo.

//////////////////////////
/cp
2013-08-25  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/54485
        * decl.c (duplicate_decls): Enforce 8.3.6/6 about default arguments
        for member functions of class templates.

/testsuite
2013-08-25  Paolo Carlini  <paolo.carl...@oracle.com>

        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.
Index: cp/decl.c
===================================================================
--- cp/decl.c   (revision 201977)
+++ cp/decl.c   (working copy)
@@ -1686,25 +1686,47 @@ duplicate_decls (tree newdecl, tree olddecl, bool
          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);
+                     }
                  }
-             }
+           }
        }
     }
 
Index: testsuite/g++.dg/other/default5.C
===================================================================
--- testsuite/g++.dg/other/default5.C   (revision 201977)
+++ testsuite/g++.dg/other/default5.C   (working copy)
@@ -43,5 +43,5 @@ template<int> struct B
   void F2(int, int, int = 0);
 };
 
-template<int N> void B<N>::F1(int, int = 0, int) {}
-template<int N> void B<N>::F2(int = 0, int, int) {}  // { dg-error "default" }
+template<int N> void B<N>::F1(int, int = 0, int) {}  // { dg-error "default 
arguments" }
+template<int N> void B<N>::F2(int = 0, int, int) {}  // { dg-error "default 
arguments|parameter 2" }
Index: testsuite/g++.dg/other/default8.C
===================================================================
--- testsuite/g++.dg/other/default8.C   (revision 0)
+++ testsuite/g++.dg/other/default8.C   (working copy)
@@ -0,0 +1,43 @@
+// PR c++54485
+
+template<typename T>
+class K1
+{
+  int fn(int, int);
+  int gn(int, int);
+};
+
+template<typename T>
+int K1<T>::fn (int a, int b = 3)      // { dg-error "default arguments" }
+{
+  return a - b;
+}
+
+template<typename T>
+int K1<T>::gn (int a = 1, int b = 3)  // { dg-error "default arguments" }
+{
+  return a - b;
+}
+
+template<typename T>
+class K2
+{
+  template<typename U>
+  int fn(int, int);
+  template<typename U>
+  int gn(int, int);
+};
+
+template<typename T>
+template<typename U>
+int K2<T>::fn (int a, int b = 3)  // { dg-error "default arguments" }
+{
+  return a - b;
+}
+
+template<typename T>
+template<typename U>
+int K2<T>::gn (int a = 1, int b = 3)  // { dg-error "default arguments" }
+{
+  return a - b;
+}
Index: testsuite/g++.dg/tc1/dr217.C
===================================================================
--- testsuite/g++.dg/tc1/dr217.C        (revision 201977)
+++ testsuite/g++.dg/tc1/dr217.C        (working copy)
@@ -10,5 +10,5 @@ struct S
 };
 
 template <class T>
-void S<T>::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<T>::foo (int = 0)  // { dg-error "" "default arguments for parameters 
of member functions of class templates can be specified in the initial 
declaration only" }
 { }
Index: testsuite/g++.old-deja/g++.mike/p1989.C
===================================================================
--- testsuite/g++.old-deja/g++.mike/p1989.C     (revision 201977)
+++ testsuite/g++.old-deja/g++.mike/p1989.C     (working copy)
@@ -108,7 +108,7 @@ List_DL<T>::prepend(const T& item)
 
 template<class T>
 void
-List_DL<T>::insert(const T& item, Pix x, bool before = TRUE)
+List_DL<T>::insert(const T& item, Pix x, bool before = TRUE)  // { dg-error 
"default arguments" }
 {
     link<T> *l = (link<T> *) x;
 

Reply via email to