This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[c++ patch] template deduction of return type
- To: gcc-patches at gcc dot gnu dot org
- Subject: [c++ patch] template deduction of return type
- From: Nathan Sidwell <nathan at codesourcery dot com>
- Date: Mon, 28 Feb 2000 10:18:37 +0000
- Organization: CodeSourcery, LLC
Hi,
here's a patch to fix template argument deduction involving the
return type of a template function. It is permitted to distinguish
template functions by return type, and hence that should be considered
when taking the address of a template function. fn_type_unification only
did this when dealing with conversion operators. This patch alters it,
so that it considers the return type, whenever it is supplied with a
non-null RETURN_TYPE. resolve_address_of_overloaded_function is
modified to pass in the desired return type. get_bindings_real is
modified to only pass a non-null RETURN_TYPE, when necessary. This
allows it to not explicitly check the return type substitution.
ok?
nathan
--
Dr Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
2000-02-28 Nathan Sidwell <nathan@codesourcery.com>
* pt.c (fn_type_unification): Unify return type, whenever
provided.
(get_bindings_real): Only pass return type when necessary.
Remove explicit return type check.
* class.c (resolve_address_of_overloaded_function): Pass desired
return type to fn_type_unification.
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/pt.c,v
retrieving revision 1.399
diff -c -3 -p -r1.399 pt.c
*** pt.c 2000/02/22 07:25:30 1.399
--- pt.c 2000/02/28 10:16:23
*************** fn_type_unification (fn, explicit_targs,
*** 7562,7573 ****
if (DECL_CONV_FN_P (fn))
{
! /* This is a template conversion operator. Use the return types
! as well as the argument types. We use it instead of 'this', since
we could be comparing conversions from different classes. */
! parms = tree_cons (NULL_TREE, TREE_TYPE (fntype),
! TREE_CHAIN (parms));
! args = tree_cons (NULL_TREE, return_type, TREE_CHAIN (args));
}
/* We allow incomplete unification without an error message here
--- 7562,7579 ----
if (DECL_CONV_FN_P (fn))
{
! /* This is a template conversion operator. Remove `this', since
we could be comparing conversions from different classes. */
! parms = TREE_CHAIN (parms);
! args = TREE_CHAIN (args);
! my_friendly_assert (return_type != NULL_TREE, 20000227);
! }
!
! if (return_type)
! {
! /* We've been given a return type to match, prepend it. */
! parms = tree_cons (NULL_TREE, TREE_TYPE (fntype), parms);
! args = tree_cons (NULL_TREE, return_type, args);
}
/* We allow incomplete unification without an error message here
*************** get_bindings_real (fn, decl, explicit_ar
*** 8793,8813 ****
i = fn_type_unification (fn, explicit_args, targs,
decl_arg_types,
! TREE_TYPE (decl_type),
DEDUCE_EXACT);
if (i != 0)
return NULL_TREE;
-
- if (check_rettype)
- {
- /* Check to see that the resulting return type is also OK. */
- tree t = tsubst (TREE_TYPE (TREE_TYPE (fn)), targs,
- /*complain=*/0, NULL_TREE);
-
- if (!same_type_p (t, TREE_TYPE (TREE_TYPE (decl))))
- return NULL_TREE;
- }
return targs;
}
--- 8799,8810 ----
i = fn_type_unification (fn, explicit_args, targs,
decl_arg_types,
! (check_rettype || DECL_CONV_FN_P (fn)
! ? TREE_TYPE (decl_type) : NULL_TREE),
DEDUCE_EXACT);
if (i != 0)
return NULL_TREE;
return targs;
}
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/class.c,v
retrieving revision 1.262
diff -c -3 -p -r1.262 class.c
*** class.c 2000/02/21 19:51:44 1.262
--- class.c 2000/02/28 10:16:25
*************** resolve_address_of_overloaded_function (
*** 5858,5863 ****
--- 5858,5864 ----
{
tree target_fn_type;
tree target_arg_types;
+ tree target_ret_type;
tree fns;
if (is_ptrmem)
*************** resolve_address_of_overloaded_function (
*** 5866,5871 ****
--- 5867,5873 ----
else
target_fn_type = TREE_TYPE (target_type);
target_arg_types = TYPE_ARG_TYPES (target_fn_type);
+ target_ret_type = TREE_TYPE (target_fn_type);
for (fns = overload; fns; fns = OVL_CHAIN (fns))
{
*************** resolve_address_of_overloaded_function (
*** 5887,5893 ****
/* Try to do argument deduction. */
targs = make_tree_vec (DECL_NTPARMS (fn));
if (fn_type_unification (fn, explicit_targs, targs,
! target_arg_types, NULL_TREE,
DEDUCE_EXACT) != 0)
/* Argument deduction failed. */
continue;
--- 5889,5895 ----
/* Try to do argument deduction. */
targs = make_tree_vec (DECL_NTPARMS (fn));
if (fn_type_unification (fn, explicit_targs, targs,
! target_arg_types, target_ret_type,
DEDUCE_EXACT) != 0)
/* Argument deduction failed. */
continue;
// Build don't link:
// Copyright (C) 2000 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 26 Feb 2000 <nathan@codesourcery.com>
// template functions can be distinguished by return type alone. The return
// type may also be a template parameter.
template <typename C> C foo (); // gets bogus error - XFAIL *-*-*
void g ()
{
int (*pfn1) () = &foo; // gets bogus error - XFAIL *-*-*
void (*pfn2) () = &foo; // gets bogus error - XFAIL *-*-*
}