OSDN Git Service

PR c++/19439
authorlmillward <lmillward@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 6 Jan 2007 01:06:04 +0000 (01:06 +0000)
committerlmillward <lmillward@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 6 Jan 2007 01:06:04 +0000 (01:06 +0000)
       * class.c (add_method): Don't wait until template
       instantiation time to complain about duplicate methods.

       * g++.dg/template/duplicate1.C: New test
       * g++.dg/template/memfriend6.C: Adjust error markers.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120520 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/duplicate1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/memfriend6.C

index 3c35e58..fc2637f 100644 (file)
@@ -1,3 +1,9 @@
+2007-01-06  Lee Millward  <lee.millward@codesourcery.com>
+
+       PR c++/19439
+       * class.c (add_method): Don't wait until template
+       instantiation time to complain about duplicate methods.
+       
 2007-01-05  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
 
        PR c/19978
index 6b195fb..b56ef84 100644 (file)
@@ -1,6 +1,7 @@
 /* Functions related to building classes and their related objects.
    Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005  Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
+   Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GCC.
@@ -898,6 +899,7 @@ add_method (tree type, tree method, tree using_decl)
   bool complete_p;
   bool insert_p = false;
   tree current_fns;
+  tree fns;
 
   if (method == error_mark_node)
     return false;
@@ -975,92 +977,83 @@ add_method (tree type, tree method, tree using_decl)
     }
   current_fns = insert_p ? NULL_TREE : VEC_index (tree, method_vec, slot);
 
-  if (processing_template_decl)
-    /* TYPE is a template class.  Don't issue any errors now; wait
-       until instantiation time to complain.  */
-    ;
-  else
+  /* Check to see if we've already got this method.  */
+  for (fns = current_fns; fns; fns = OVL_NEXT (fns))
     {
-      tree fns;
-
-      /* Check to see if we've already got this method.  */
-      for (fns = current_fns; fns; fns = OVL_NEXT (fns))
-       {
-         tree fn = OVL_CURRENT (fns);
-         tree fn_type;
-         tree method_type;
-         tree parms1;
-         tree parms2;
+      tree fn = OVL_CURRENT (fns);
+      tree fn_type;
+      tree method_type;
+      tree parms1;
+      tree parms2;
 
-         if (TREE_CODE (fn) != TREE_CODE (method))
-           continue;
+      if (TREE_CODE (fn) != TREE_CODE (method))
+       continue;
 
-         /* [over.load] Member function declarations with the
-            same name and the same parameter types cannot be
-            overloaded if any of them is a static member
-            function declaration.
-
-            [namespace.udecl] When a using-declaration brings names
-            from a base class into a derived class scope, member
-            functions in the derived class override and/or hide member
-            functions with the same name and parameter types in a base
-            class (rather than conflicting).  */
-         fn_type = TREE_TYPE (fn);
-         method_type = TREE_TYPE (method);
-         parms1 = TYPE_ARG_TYPES (fn_type);
-         parms2 = TYPE_ARG_TYPES (method_type);
-
-         /* Compare the quals on the 'this' parm.  Don't compare
-            the whole types, as used functions are treated as
-            coming from the using class in overload resolution.  */
-         if (! DECL_STATIC_FUNCTION_P (fn)
-             && ! DECL_STATIC_FUNCTION_P (method)
-             && (TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms1)))
-                 != TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms2)))))
-           continue;
+      /* [over.load] Member function declarations with the
+        same name and the same parameter types cannot be
+        overloaded if any of them is a static member
+        function declaration.
+
+        [namespace.udecl] When a using-declaration brings names
+        from a base class into a derived class scope, member
+        functions in the derived class override and/or hide member
+        functions with the same name and parameter types in a base
+        class (rather than conflicting).  */
+      fn_type = TREE_TYPE (fn);
+      method_type = TREE_TYPE (method);
+      parms1 = TYPE_ARG_TYPES (fn_type);
+      parms2 = TYPE_ARG_TYPES (method_type);
+
+      /* Compare the quals on the 'this' parm.  Don't compare
+        the whole types, as used functions are treated as
+        coming from the using class in overload resolution.  */
+      if (! DECL_STATIC_FUNCTION_P (fn)
+         && ! DECL_STATIC_FUNCTION_P (method)
+         && (TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms1)))
+             != TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms2)))))
+       continue;
 
-         /* For templates, the return type and template parameters
-            must be identical.  */
-         if (TREE_CODE (fn) == TEMPLATE_DECL
-             && (!same_type_p (TREE_TYPE (fn_type),
-                               TREE_TYPE (method_type))
-                 || !comp_template_parms (DECL_TEMPLATE_PARMS (fn),
-                                          DECL_TEMPLATE_PARMS (method))))
-           continue;
+      /* For templates, the return type and template parameters
+        must be identical.  */
+      if (TREE_CODE (fn) == TEMPLATE_DECL
+         && (!same_type_p (TREE_TYPE (fn_type),
+                           TREE_TYPE (method_type))
+             || !comp_template_parms (DECL_TEMPLATE_PARMS (fn),
+                                      DECL_TEMPLATE_PARMS (method))))
+       continue;
 
-         if (! DECL_STATIC_FUNCTION_P (fn))
-           parms1 = TREE_CHAIN (parms1);
-         if (! DECL_STATIC_FUNCTION_P (method))
-           parms2 = TREE_CHAIN (parms2);
+      if (! DECL_STATIC_FUNCTION_P (fn))
+       parms1 = TREE_CHAIN (parms1);
+      if (! DECL_STATIC_FUNCTION_P (method))
+       parms2 = TREE_CHAIN (parms2);
 
-         if (compparms (parms1, parms2)
-             && (!DECL_CONV_FN_P (fn)
-                 || same_type_p (TREE_TYPE (fn_type),
-                                 TREE_TYPE (method_type))))
+      if (compparms (parms1, parms2)
+         && (!DECL_CONV_FN_P (fn)
+             || same_type_p (TREE_TYPE (fn_type),
+                             TREE_TYPE (method_type))))
+       {
+         if (using_decl)
            {
-             if (using_decl)
-               {
-                 if (DECL_CONTEXT (fn) == type)
-                   /* Defer to the local function.  */
-                   return false;
-                 if (DECL_CONTEXT (fn) == DECL_CONTEXT (method))
-                   error ("repeated using declaration %q+D", using_decl);
-                 else
-                   error ("using declaration %q+D conflicts with a previous using declaration",
-                          using_decl);
-               }
+             if (DECL_CONTEXT (fn) == type)
+               /* Defer to the local function.  */
+               return false;
+             if (DECL_CONTEXT (fn) == DECL_CONTEXT (method))
+               error ("repeated using declaration %q+D", using_decl);
              else
-               {
-                 error ("%q+#D cannot be overloaded", method);
-                 error ("with %q+#D", fn);
-               }
-
-             /* We don't call duplicate_decls here to merge the
-                declarations because that will confuse things if the
-                methods have inline definitions.  In particular, we
-                will crash while processing the definitions.  */
-             return false;
+               error ("using declaration %q+D conflicts with a previous using declaration",
+                      using_decl);
+           }
+         else
+           {
+             error ("%q+#D cannot be overloaded", method);
+             error ("with %q+#D", fn);
            }
+
+         /* We don't call duplicate_decls here to merge the
+            declarations because that will confuse things if the
+            methods have inline definitions.  In particular, we
+            will crash while processing the definitions.  */
+         return false;
        }
     }
 
index 783d2c6..7f815e4 100644 (file)
@@ -1,3 +1,9 @@
+2006-01-06  Lee Millward  <lee.millward@codesourcery.com>
+
+       PR c++/19439
+       * g++.dg/template/duplicate1.C: New test
+       * g++.dg/template/memfriend6.C: Adjust error markers.
+       
 2007-01-05  Andrew Pinski  <Andrew_Pinski@playstation.sony.com>
 
        PR tree-opt/30385
diff --git a/gcc/testsuite/g++.dg/template/duplicate1.C b/gcc/testsuite/g++.dg/template/duplicate1.C
new file mode 100644 (file)
index 0000000..c9cdab4
--- /dev/null
@@ -0,0 +1,7 @@
+//PR c++/19439
+
+template<int> struct A
+{
+  ~A() {}      // { dg-error "with" }
+  ~A() {}      // { dg-error "cannot be overloaded" }
+};
index 21d7996..5f82339 100644 (file)
@@ -8,8 +8,8 @@
 
 template <class T> struct A {
   template <class U> void f(U);                // { dg-error "candidate" }
-  void g();                            // { dg-error "candidate" }
-  void h();                            // { dg-error "candidate" }
+  void g();                            // { dg-error "candidate|with" }
+  void h();                            // { dg-error "candidate|with" }
   void i(int);                         // { dg-error "candidate" }
 };
 
@@ -17,7 +17,7 @@ class C {
   int ii;
   template <class U> friend void A<U>::f(U);   // { dg-error "not match" }
   template <class U> template <class V>
-    friend void A<U>::g();                     // { dg-error "not match" }
-  template <class U> friend int A<U>::h();     // { dg-error "not match" }
+    friend void A<U>::g();                     // { dg-error "not match|cannot be overloaded" }
+  template <class U> friend int A<U>::h();     // { dg-error "not match|cannot be overloaded" }
   template <class U> friend void A<U>::i(char);        // { dg-error "not match" }
 };