This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[c++ patch] template deduction of return type


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 *-*-*
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]