re PR c++/19439 (Duplicate destructor accepted)

PR c++/19439
       * 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.

From-SVN: r120520
This commit is contained in:
Lee Millward 2007-01-06 01:06:04 +00:00 committed by Lee Millward
parent 70973361c1
commit fc40d49c4e
5 changed files with 97 additions and 85 deletions

View 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

View 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;
tree fn = OVL_CURRENT (fns);
tree fn_type;
tree method_type;
tree parms1;
tree parms2;
/* Check to see if we've already got this method. */
for (fns = current_fns; fns; fns = OVL_NEXT (fns))
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;
/* 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 (compparms (parms1, parms2)
&& (!DECL_CONV_FN_P (fn)
|| same_type_p (TREE_TYPE (fn_type),
TREE_TYPE (method_type))))
{
tree fn = OVL_CURRENT (fns);
tree fn_type;
tree method_type;
tree parms1;
tree parms2;
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;
/* 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 (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;
}
}

View 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

View File

@ -0,0 +1,7 @@
//PR c++/19439
template<int> struct A
{
~A() {} // { dg-error "with" }
~A() {} // { dg-error "cannot be overloaded" }
};

View 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" }
};