aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/class.c149
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/template/duplicate1.C7
-rw-r--r--gcc/testsuite/g++.dg/template/memfriend6.C8
5 files changed, 94 insertions, 82 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 3c35e58..fc2637f 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 6b195fb..b56ef84 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -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;
}
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 783d2c6..7f815e4 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..c9cdab4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/duplicate1.C
@@ -0,0 +1,7 @@
+//PR c++/19439
+
+template<int> struct A
+{
+ ~A() {} // { dg-error "with" }
+ ~A() {} // { dg-error "cannot be overloaded" }
+};
diff --git a/gcc/testsuite/g++.dg/template/memfriend6.C b/gcc/testsuite/g++.dg/template/memfriend6.C
index 21d7996..5f82339 100644
--- a/gcc/testsuite/g++.dg/template/memfriend6.C
+++ b/gcc/testsuite/g++.dg/template/memfriend6.C
@@ -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" }
};