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]
Other format: [Raw text]

C++ PATCH: PR 5296


This patch fixes a template argument deduction failure.

Tested on i686-pc-linux-gnu, applied on the mainline and on the
branch.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2003-09-08  Mark Mitchell  <mark@codesourcery.com>

	PR c++/5296
	* pt.c (try_one_overload): Add addr_p parameter.
	(resolve_overloaded_unification): Pass it.

2003-09-08  Mark Mitchell  <mark@codesourcery.com>

	PR c++/5296
	* g++.dg/rtti/typeid2.C: New test.

Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.775
diff -c -5 -p -r1.775 pt.c
*** cp/pt.c	5 Sep 2003 18:04:15 -0000	1.775
--- cp/pt.c	8 Sep 2003 16:37:13 -0000
*************** static htab_t local_specializations;
*** 91,101 ****
  static void push_access_scope (tree);
  static void pop_access_scope (tree);
  static int resolve_overloaded_unification (tree, tree, tree, tree,
  					   unification_kind_t, int);
  static int try_one_overload (tree, tree, tree, tree, tree,
! 			     unification_kind_t, int);
  static int unify (tree, tree, tree, tree, int);
  static void add_pending_template (tree);
  static void reopen_tinst_level (tree);
  static tree classtype_mangled_name (tree);
  static char* mangle_class_name_for_template (const char *, tree, tree);
--- 91,101 ----
  static void push_access_scope (tree);
  static void pop_access_scope (tree);
  static int resolve_overloaded_unification (tree, tree, tree, tree,
  					   unification_kind_t, int);
  static int try_one_overload (tree, tree, tree, tree, tree,
! 			     unification_kind_t, int, bool);
  static int unify (tree, tree, tree, tree, int);
  static void add_pending_template (tree);
  static void reopen_tinst_level (tree);
  static tree classtype_mangled_name (tree);
  static char* mangle_class_name_for_template (const char *, tree, tree);
*************** resolve_overloaded_unification (tree tpa
*** 8922,8934 ****
                                  unification_kind_t strict,
  				int sub_strict)
  {
    tree tempargs = copy_node (targs);
    int good = 0;
  
    if (TREE_CODE (arg) == ADDR_EXPR)
!     arg = TREE_OPERAND (arg, 0);
  
    if (TREE_CODE (arg) == COMPONENT_REF)
      /* Handle `&x' where `x' is some static or non-static member
         function name.  */
      arg = TREE_OPERAND (arg, 1);
--- 8922,8940 ----
                                  unification_kind_t strict,
  				int sub_strict)
  {
    tree tempargs = copy_node (targs);
    int good = 0;
+   bool addr_p;
  
    if (TREE_CODE (arg) == ADDR_EXPR)
!     {
!       arg = TREE_OPERAND (arg, 0);
!       addr_p = true;
!     }
!   else
!     addr_p = false;
  
    if (TREE_CODE (arg) == COMPONENT_REF)
      /* Handle `&x' where `x' is some static or non-static member
         function name.  */
      arg = TREE_OPERAND (arg, 1);
*************** resolve_overloaded_unification (tree tpa
*** 8960,8988 ****
  	  subargs = get_bindings_overload (fn, DECL_TEMPLATE_RESULT (fn),
  					   expl_subargs);
  	  if (subargs)
  	    {
  	      elem = tsubst (TREE_TYPE (fn), subargs, tf_none, NULL_TREE);
! 	      if (TREE_CODE (elem) == METHOD_TYPE)
! 		elem = build_ptrmemfunc_type (build_pointer_type (elem));
! 	      good += try_one_overload (tparms, targs, tempargs, parm, elem,
! 					strict, sub_strict);
  	    }
  	}
      }
    else if (TREE_CODE (arg) == OVERLOAD
  	   || TREE_CODE (arg) == FUNCTION_DECL)
      {
        for (; arg; arg = OVL_NEXT (arg))
! 	{
! 	  tree type = TREE_TYPE (OVL_CURRENT (arg));
! 	  if (TREE_CODE (type) == METHOD_TYPE)
! 	    type = build_ptrmemfunc_type (build_pointer_type (type));
! 	  good += try_one_overload (tparms, targs, tempargs, parm,
! 				    type,
! 				    strict, sub_strict);
! 	}
      }
    else
      abort ();
  
    /* [temp.deduct.type] A template-argument can be deduced from a pointer
--- 8966,8987 ----
  	  subargs = get_bindings_overload (fn, DECL_TEMPLATE_RESULT (fn),
  					   expl_subargs);
  	  if (subargs)
  	    {
  	      elem = tsubst (TREE_TYPE (fn), subargs, tf_none, NULL_TREE);
! 	      good += try_one_overload (tparms, targs, tempargs, parm, 
! 					elem, strict, sub_strict, addr_p);
  	    }
  	}
      }
    else if (TREE_CODE (arg) == OVERLOAD
  	   || TREE_CODE (arg) == FUNCTION_DECL)
      {
        for (; arg; arg = OVL_NEXT (arg))
! 	good += try_one_overload (tparms, targs, tempargs, parm,
! 				  TREE_TYPE (OVL_CURRENT (arg)),
! 				  strict, sub_strict, addr_p);
      }
    else
      abort ();
  
    /* [temp.deduct.type] A template-argument can be deduced from a pointer
*************** resolve_overloaded_unification (tree tpa
*** 9007,9026 ****
  }
  
  /* Subroutine of resolve_overloaded_unification; does deduction for a single
     overload.  Fills TARGS with any deduced arguments, or error_mark_node if
     different overloads deduce different arguments for a given parm.
     Returns 1 on success.  */
  
  static int
  try_one_overload (tree tparms,
                    tree orig_targs,
                    tree targs, 
                    tree parm, 
                    tree arg, 
                    unification_kind_t strict,
! 		  int sub_strict)
  {
    int nargs;
    tree tempargs;
    int i;
  
--- 9006,9029 ----
  }
  
  /* Subroutine of resolve_overloaded_unification; does deduction for a single
     overload.  Fills TARGS with any deduced arguments, or error_mark_node if
     different overloads deduce different arguments for a given parm.
+    ADDR_P is true if the expression for which deduction is being
+    performed was of the form "& fn" rather than simply "fn".
+ 
     Returns 1 on success.  */
  
  static int
  try_one_overload (tree tparms,
                    tree orig_targs,
                    tree targs, 
                    tree parm, 
                    tree arg, 
                    unification_kind_t strict,
! 		  int sub_strict,
! 		  bool addr_p)
  {
    int nargs;
    tree tempargs;
    int i;
  
*************** try_one_overload (tree tparms,
*** 9031,9040 ****
--- 9034,9048 ----
  
       So if this is a template, just return success.  */
  
    if (uses_template_parms (arg))
      return 1;
+ 
+   if (TREE_CODE (arg) == METHOD_TYPE)
+     arg = build_ptrmemfunc_type (build_pointer_type (arg));
+   else if (addr_p)
+     arg = build_pointer_type (arg);
  
    sub_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg);
  
    /* We don't copy orig_targs for this because if we have already deduced
       some template args from previous args, unify would complain when we
Index: testsuite/g++.dg/rtti/typeid2.C
===================================================================
RCS file: testsuite/g++.dg/rtti/typeid2.C
diff -N testsuite/g++.dg/rtti/typeid2.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/rtti/typeid2.C	8 Sep 2003 16:39:38 -0000
***************
*** 0 ****
--- 1,15 ----
+ // { dg-do run }
+ 
+ #include <typeinfo>
+ 
+ template <typename T>  const char *print_type (const T &) {
+   return typeid(T).name();
+ }
+ 
+ /* no template */      void pp1 (int) {}
+ template <typename X>  void pp2 (X)   {}
+ 
+ int main () {
+   if (print_type (&pp1) != print_type (&pp2<int>))
+     return 1;
+ }


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