PATCH for Re: Problem with overload resolution.

Mark Mitchell mark@markmitchell.com
Sun May 24 18:56:00 GMT 1998


Scott --

  Here's a patch for your problem.  I didn't go quite far enough
cleaning up overload resolution last week; there were a couple of
remaining gotchas.  Jason, is this OK?

-- 
Mark Mitchell 			mark@markmitchell.com
Mark Mitchell Consulting	http://www.markmitchell.com

1998-05-24  Mark Mitchell  <mark@markmitchell.com>

	* call.c (maybe_handle_implicit_object): Handle QUAL_CONVs.  Make
	sure the type of the REF_BIND is a reference type.
	(maybe_handle_ref_bind, compare_ics): Rename reference_type* to
	ref_to_type* for clarity.

Index: overload6.C
===================================================================
RCS file: overload6.C
diff -N overload6.C
*** /dev/null	Mon Dec 31 20:00:00 1979
--- overload6.C	Sun May 24 17:20:20 1998
***************
*** 0 ****
--- 1,18 ----
+ extern "C" void abort();
+ 
+ struct S1
+ {
+   int f() { return 0; }
+   int f() const { return 1; }
+ };
+ 
+ struct S2 : public S1
+ {
+ };
+ 
+ int main()
+ {
+   S2 s2;
+   if (s2.f() != 0)
+     abort ();
+ }
Index: call.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/call.c,v
retrieving revision 1.79
diff -c -p -r1.79 call.c
*** call.c	1998/05/22 23:13:25	1.79
--- call.c	1998/05/25 00:25:44
*************** maybe_handle_implicit_object (ics)
*** 3739,3761 ****
  	 member and cv is the cv-qualification on the member
  	 function declaration.  */
        tree t = *ics;
        if (TREE_CODE (t) == PTR_CONV)
  	t = TREE_OPERAND (t, 0);
        t = build1 (IDENTITY_CONV, TREE_TYPE (TREE_TYPE (t)), NULL_TREE);
!       t = build_conv (REF_BIND, TREE_TYPE (*ics), t);
        ICS_STD_RANK (t) = ICS_STD_RANK (*ics);
        *ics = t;
      }
  }
  
! /* If ICS is a REF_BIND, modify it appropriately, set ORIG_TO_TYPE
     to the type the reference originally referred to, and return 1.
     Otherwise, return 0.  */
  
  static int
! maybe_handle_ref_bind (ics, reference_type)
       tree* ics;
!      tree* reference_type;
  {
    if (TREE_CODE (*ics) == REF_BIND)
      {
--- 3739,3765 ----
  	 member and cv is the cv-qualification on the member
  	 function declaration.  */
        tree t = *ics;
+       if (TREE_CODE (t) == QUAL_CONV)
+ 	t = TREE_OPERAND (t, 0);
        if (TREE_CODE (t) == PTR_CONV)
  	t = TREE_OPERAND (t, 0);
        t = build1 (IDENTITY_CONV, TREE_TYPE (TREE_TYPE (t)), NULL_TREE);
!       t = build_conv (REF_BIND, 
! 		      build_reference_type (TREE_TYPE (TREE_TYPE (*ics))), 
! 		      t);
        ICS_STD_RANK (t) = ICS_STD_RANK (*ics);
        *ics = t;
      }
  }
  
! /* If ICS is a REF_BIND, modify it appropriately, set REF_TO_TYPE
     to the type the reference originally referred to, and return 1.
     Otherwise, return 0.  */
  
  static int
! maybe_handle_ref_bind (ics, ref_to_type)
       tree* ics;
!      tree* ref_to_type;
  {
    if (TREE_CODE (*ics) == REF_BIND)
      {
*************** maybe_handle_ref_bind (ics, reference_ty
*** 3788,3798 ****
  
        tree old_ics = *ics;
  
!       *reference_type = TREE_TYPE (TREE_TYPE (*ics));
        *ics = TREE_OPERAND (*ics, 0);
        if (TREE_CODE (*ics) == IDENTITY_CONV
! 	  && is_properly_derived_from (TREE_TYPE (*ics), *reference_type))
! 	*ics = build_conv (BASE_CONV, *reference_type, *ics);
        ICS_USER_FLAG (*ics) = ICS_USER_FLAG (old_ics);
        ICS_BAD_FLAG (*ics) = ICS_BAD_FLAG (old_ics);
        
--- 3792,3802 ----
  
        tree old_ics = *ics;
  
!       *ref_to_type = TREE_TYPE (TREE_TYPE (*ics));
        *ics = TREE_OPERAND (*ics, 0);
        if (TREE_CODE (*ics) == IDENTITY_CONV
! 	  && is_properly_derived_from (TREE_TYPE (*ics), *ref_to_type))
! 	*ics = build_conv (BASE_CONV, *ref_to_type, *ics);
        ICS_USER_FLAG (*ics) = ICS_USER_FLAG (old_ics);
        ICS_BAD_FLAG (*ics) = ICS_BAD_FLAG (old_ics);
        
*************** compare_ics (ics1, ics2)
*** 3823,3842 ****
    tree deref_to_type2;
  
    /* REF_BINDING is non-zero if the result of the conversion sequence
!      is a reference type.   In that case REFERENCE_TYPE is the
!      reference type.  */
    int ref_binding1;
    int ref_binding2;
!   tree reference_type1;
!   tree reference_type2;
  
    /* Handle implicit object parameters.  */
    maybe_handle_implicit_object (&ics1);
    maybe_handle_implicit_object (&ics2);
  
    /* Handle reference parameters.  */
!   ref_binding1 = maybe_handle_ref_bind (&ics1, &reference_type1);
!   ref_binding2 = maybe_handle_ref_bind (&ics2, &reference_type2);
  
    /* [over.ics.rank]
  
--- 3827,3846 ----
    tree deref_to_type2;
  
    /* REF_BINDING is non-zero if the result of the conversion sequence
!      is a reference type.   In that case REF_TO_TYPE is the
!      type referred to by the reference.  */
    int ref_binding1;
    int ref_binding2;
!   tree ref_to_type1;
!   tree ref_to_type2;
  
    /* Handle implicit object parameters.  */
    maybe_handle_implicit_object (&ics1);
    maybe_handle_implicit_object (&ics2);
  
    /* Handle reference parameters.  */
!   ref_binding1 = maybe_handle_ref_bind (&ics1, &ref_to_type1);
!   ref_binding2 = maybe_handle_ref_bind (&ics2, &ref_to_type2);
  
    /* [over.ics.rank]
  
*************** compare_ics (ics1, ics2)
*** 4132,4138 ****
    if (ref_binding1 && ref_binding2
        && comptypes (TYPE_MAIN_VARIANT (to_type1),
  		    TYPE_MAIN_VARIANT (to_type2), 1))
!     return comp_cv_qualification (reference_type2, reference_type1);
  
    /* Neither conversion sequence is better than the other.  */
    return 0;
--- 4136,4142 ----
    if (ref_binding1 && ref_binding2
        && comptypes (TYPE_MAIN_VARIANT (to_type1),
  		    TYPE_MAIN_VARIANT (to_type2), 1))
!     return comp_cv_qualification (ref_to_type2, ref_to_type1);
  
    /* Neither conversion sequence is better than the other.  */
    return 0;



More information about the Gcc-bugs mailing list