re PR c++/9053 (g++ confused about ambiguity of overloaded function templates)
cp: PR c++/9053 * decl.c (duplicate_decls): Templates may be disambiguated by return type. PR c++/8702 * decl2.c (check_classfn): Use lookup_fnfield_1. List all conversion operators on failure. testsuite * g++.dg/lookup/decl1.C: New test. * g++.dg/lookup/decl2.C: New test. From-SVN: r60482
This commit is contained in:
parent
40aa9d95e2
commit
b9201622ae
|
@ -1,3 +1,13 @@
|
|||
2002-12-24 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
PR c++/9053
|
||||
* decl.c (duplicate_decls): Templates may be disambiguated by
|
||||
return type.
|
||||
|
||||
PR c++/8702
|
||||
* decl2.c (check_classfn): Use lookup_fnfield_1. List all
|
||||
conversion operators on failure.
|
||||
|
||||
2002-12-23 Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||
|
||||
* call.c (tourney, build_field_call, equal_functions, joust)
|
||||
|
|
|
@ -3212,7 +3212,11 @@ duplicate_decls (newdecl, olddecl)
|
|||
&& compparms (TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl))),
|
||||
TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (newdecl))))
|
||||
&& comp_template_parms (DECL_TEMPLATE_PARMS (newdecl),
|
||||
DECL_TEMPLATE_PARMS (olddecl)))
|
||||
DECL_TEMPLATE_PARMS (olddecl))
|
||||
/* Template functions can be disambiguated by
|
||||
return type. */
|
||||
&& same_type_p (TREE_TYPE (TREE_TYPE (newdecl)),
|
||||
TREE_TYPE (TREE_TYPE (olddecl))))
|
||||
{
|
||||
error ("new declaration `%#D'", newdecl);
|
||||
cp_error_at ("ambiguates old declaration `%#D'", olddecl);
|
||||
|
|
143
gcc/cp/decl2.c
143
gcc/cp/decl2.c
|
@ -676,11 +676,7 @@ tree
|
|||
check_classfn (ctype, function)
|
||||
tree ctype, function;
|
||||
{
|
||||
tree fn_name = DECL_NAME (function);
|
||||
tree fndecl, fndecls;
|
||||
tree method_vec = CLASSTYPE_METHOD_VEC (complete_type (ctype));
|
||||
tree *methods = 0;
|
||||
tree *end = 0;
|
||||
int ix;
|
||||
|
||||
if (DECL_USE_TEMPLATE (function)
|
||||
&& !(TREE_CODE (function) == TEMPLATE_DECL
|
||||
|
@ -697,81 +693,90 @@ check_classfn (ctype, function)
|
|||
reason we should, either. We let our callers know we didn't
|
||||
find the method, but we don't complain. */
|
||||
return NULL_TREE;
|
||||
|
||||
if (method_vec != 0)
|
||||
|
||||
ix = lookup_fnfields_1 (complete_type (ctype),
|
||||
DECL_CONSTRUCTOR_P (function) ? ctor_identifier :
|
||||
DECL_DESTRUCTOR_P (function) ? dtor_identifier :
|
||||
DECL_NAME (function));
|
||||
|
||||
if (ix >= 0)
|
||||
{
|
||||
methods = &TREE_VEC_ELT (method_vec, 0);
|
||||
end = TREE_VEC_END (method_vec);
|
||||
|
||||
/* First suss out ctors and dtors. */
|
||||
if (*methods && fn_name == DECL_NAME (OVL_CURRENT (*methods))
|
||||
&& DECL_CONSTRUCTOR_P (function))
|
||||
goto got_it;
|
||||
if (*++methods && fn_name == DECL_NAME (OVL_CURRENT (*methods))
|
||||
&& DECL_DESTRUCTOR_P (function))
|
||||
goto got_it;
|
||||
|
||||
while (++methods != end && *methods)
|
||||
tree methods = CLASSTYPE_METHOD_VEC (ctype);
|
||||
tree fndecls, fndecl;
|
||||
bool is_conv_op;
|
||||
const char *format = NULL;
|
||||
|
||||
for (fndecls = TREE_VEC_ELT (methods, ix);
|
||||
fndecls; fndecls = OVL_NEXT (fndecls))
|
||||
{
|
||||
fndecl = *methods;
|
||||
if (fn_name == DECL_NAME (OVL_CURRENT (*methods)))
|
||||
tree p1, p2;
|
||||
|
||||
fndecl = OVL_CURRENT (fndecls);
|
||||
p1 = TYPE_ARG_TYPES (TREE_TYPE (function));
|
||||
p2 = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
|
||||
|
||||
/* We cannot simply call decls_match because this doesn't
|
||||
work for static member functions that are pretending to
|
||||
be methods, and because the name may have been changed by
|
||||
asm("new_name"). */
|
||||
|
||||
/* Get rid of the this parameter on functions that become
|
||||
static. */
|
||||
if (DECL_STATIC_FUNCTION_P (fndecl)
|
||||
&& TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE)
|
||||
p1 = TREE_CHAIN (p1);
|
||||
|
||||
if (same_type_p (TREE_TYPE (TREE_TYPE (function)),
|
||||
TREE_TYPE (TREE_TYPE (fndecl)))
|
||||
&& compparms (p1, p2)
|
||||
&& (DECL_TEMPLATE_SPECIALIZATION (function)
|
||||
== DECL_TEMPLATE_SPECIALIZATION (fndecl))
|
||||
&& (!DECL_TEMPLATE_SPECIALIZATION (function)
|
||||
|| (DECL_TI_TEMPLATE (function)
|
||||
== DECL_TI_TEMPLATE (fndecl))))
|
||||
return fndecl;
|
||||
}
|
||||
error ("prototype for `%#D' does not match any in class `%T'",
|
||||
function, ctype);
|
||||
is_conv_op = DECL_CONV_FN_P (fndecl);
|
||||
|
||||
if (is_conv_op)
|
||||
ix = CLASSTYPE_FIRST_CONVERSION_SLOT;
|
||||
fndecls = TREE_VEC_ELT (methods, ix);
|
||||
while (fndecls)
|
||||
{
|
||||
fndecl = OVL_CURRENT (fndecls);
|
||||
fndecls = OVL_NEXT (fndecls);
|
||||
|
||||
if (!fndecls && is_conv_op)
|
||||
{
|
||||
got_it:
|
||||
for (fndecls = *methods; fndecls != NULL_TREE;
|
||||
fndecls = OVL_NEXT (fndecls))
|
||||
if (TREE_VEC_LENGTH (methods) > ix)
|
||||
{
|
||||
fndecl = OVL_CURRENT (fndecls);
|
||||
|
||||
/* We cannot simply call decls_match because this
|
||||
doesn't work for static member functions that are
|
||||
pretending to be methods, and because the name
|
||||
may have been changed by asm("new_name"). */
|
||||
if (DECL_NAME (function) == DECL_NAME (fndecl))
|
||||
ix++;
|
||||
fndecls = TREE_VEC_ELT (methods, ix);
|
||||
if (!DECL_CONV_FN_P (OVL_CURRENT (fndecls)))
|
||||
{
|
||||
tree p1 = TYPE_ARG_TYPES (TREE_TYPE (function));
|
||||
tree p2 = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
|
||||
|
||||
/* Get rid of the this parameter on functions that become
|
||||
static. */
|
||||
if (DECL_STATIC_FUNCTION_P (fndecl)
|
||||
&& TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE)
|
||||
p1 = TREE_CHAIN (p1);
|
||||
|
||||
if (same_type_p (TREE_TYPE (TREE_TYPE (function)),
|
||||
TREE_TYPE (TREE_TYPE (fndecl)))
|
||||
&& compparms (p1, p2)
|
||||
&& (DECL_TEMPLATE_SPECIALIZATION (function)
|
||||
== DECL_TEMPLATE_SPECIALIZATION (fndecl))
|
||||
&& (!DECL_TEMPLATE_SPECIALIZATION (function)
|
||||
|| (DECL_TI_TEMPLATE (function)
|
||||
== DECL_TI_TEMPLATE (fndecl))))
|
||||
return fndecl;
|
||||
fndecls = NULL_TREE;
|
||||
is_conv_op = false;
|
||||
}
|
||||
}
|
||||
break; /* loser */
|
||||
else
|
||||
is_conv_op = false;
|
||||
}
|
||||
if (format)
|
||||
format = " %#D";
|
||||
else if (fndecls)
|
||||
format = "candidates are: %#D";
|
||||
else
|
||||
format = "candidate is: %#D";
|
||||
cp_error_at (format, fndecl);
|
||||
}
|
||||
}
|
||||
|
||||
if (methods != end && *methods)
|
||||
{
|
||||
tree fndecl = *methods;
|
||||
error ("prototype for `%#D' does not match any in class `%T'",
|
||||
function, ctype);
|
||||
cp_error_at ("candidate%s: %+#D", OVL_NEXT (fndecl) ? "s are" : " is",
|
||||
OVL_CURRENT (fndecl));
|
||||
while (fndecl = OVL_NEXT (fndecl), fndecl)
|
||||
cp_error_at (" %#D", OVL_CURRENT(fndecl));
|
||||
}
|
||||
else if (!COMPLETE_TYPE_P (ctype))
|
||||
cxx_incomplete_type_error (function, ctype);
|
||||
else
|
||||
{
|
||||
methods = 0;
|
||||
if (!COMPLETE_TYPE_P (ctype))
|
||||
cxx_incomplete_type_error (function, ctype);
|
||||
else
|
||||
error ("no `%#D' member function declared in class `%T'",
|
||||
function, ctype);
|
||||
}
|
||||
error ("no `%#D' member function declared in class `%T'",
|
||||
function, ctype);
|
||||
|
||||
/* If we did not find the method in the class, add it to avoid
|
||||
spurious errors (unless the CTYPE is not yet defined, in which
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2002-12-24 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* g++.dg/lookup/decl1.C: New test.
|
||||
* g++.dg/lookup/decl2.C: New test.
|
||||
|
||||
2002-12-24 Joseph S. Myers <jsm@polyomino.org.uk>
|
||||
|
||||
* g++.dg/init/new1.C, g++.dg/template/alignof1.C,
|
||||
|
@ -12,9 +17,9 @@
|
|||
|
||||
2002-12-23 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* testsuite/gcc.dg/i386-bitfield3.c: New test.
|
||||
* gcc.dg/i386-bitfield3.c: New test.
|
||||
|
||||
* testsuite/gcc.dg/i386-bitfield2.c: New test.
|
||||
* gcc.dg/i386-bitfield2.c: New test.
|
||||
|
||||
2002-12-22 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
// { dg-do compile }
|
||||
|
||||
// Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
// Contributed by Nathan Sidwell 24 Dec 2002 <nathan@codesourcery.com>
|
||||
|
||||
// PR 8702. Failure to match templates.
|
||||
|
||||
template <typename X> struct C1{};
|
||||
|
||||
template <typename X>
|
||||
struct C2 {
|
||||
template<typename Y> operator C1<Y>();
|
||||
template<typename Y> operator C2<Y>();
|
||||
};
|
||||
|
||||
template<typename X> template<typename Y>
|
||||
C2<X>::operator C1<Y>()
|
||||
{
|
||||
return C1<Y>();
|
||||
}
|
||||
|
||||
struct A
|
||||
{
|
||||
operator int (); // { dg-error "operator" "" }
|
||||
operator float (); // { dg-error "operator" "" }
|
||||
operator float () const; // { dg-error "operator" "" }
|
||||
template <typename T> operator T * (); // { dg-error "candidates" "" }
|
||||
};
|
||||
|
||||
A::operator short () { // { dg-error "prototype for" "" }
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
// { dg-do compile }
|
||||
|
||||
// Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
// Contributed by Nathan Sidwell 24 Dec 2002 <nathan@codesourcery.com>
|
||||
// Source Martin Buchholz martin@xemacs.org
|
||||
|
||||
// PR 9053. Failed to consider templates that are disambiguated by
|
||||
// return type.
|
||||
|
||||
template <typename T> class bar;
|
||||
template <> struct bar<const char*> { typedef void type; };
|
||||
template <typename T> class qux;
|
||||
template <> struct qux<int> { typedef void type; };
|
||||
|
||||
template <typename T>
|
||||
typename bar<T>::type foo (T t) { }
|
||||
|
||||
template <typename T>
|
||||
typename qux<T>::type foo (T t) { }
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
foo ("foo");
|
||||
foo (7);
|
||||
}
|
Loading…
Reference in New Issue