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