diff options
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/class.c | 149 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/duplicate1.C | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/memfriend6.C | 8 |
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" } }; |