From b0385db881d09789d60be06a6bb78246fba4463a Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Fri, 23 Jul 1999 20:53:54 +0000 Subject: [PATCH] call.c (reference_binding): Tweak. * call.c (reference_binding): Tweak. (mayble_handle_implicit_object): Use direct_reference_binding to create the right implicit conversion sequence. From-SVN: r28228 --- gcc/cp/ChangeLog | 6 +++++ gcc/cp/call.c | 22 +++++++++++++------ gcc/testsuite/g++.old-deja/g++.other/covar1.C | 10 +++++++++ gcc/testsuite/g++.old-deja/g++.other/ref2.C | 15 +++++++++++++ 4 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.old-deja/g++.other/covar1.C create mode 100644 gcc/testsuite/g++.old-deja/g++.other/ref2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 78440927368..f08254f858c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +1999-07-23 Mark Mitchell + + * call.c (reference_binding): Tweak. + (mayble_handle_implicit_object): Use direct_reference_binding to + create the right implicit conversion sequence. + 1999-07-22 Mark Mitchell * pt.c (convert_nontype_argument): Don't call decl_constant_value diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 22f30dcc46b..6e75e94dd0b 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -1005,9 +1005,6 @@ reference_binding (rto, rfrom, expr, flags) from = TREE_TYPE (expr); } - related_p = reference_related_p (to, from); - compatible_p = reference_compatible_p (to, from); - if (TREE_CODE (from) == REFERENCE_TYPE) { /* Anything with reference type is an lvalue. */ @@ -1017,6 +1014,12 @@ reference_binding (rto, rfrom, expr, flags) else if (expr) lvalue_p = real_lvalue_p (expr); + /* Figure out whether or not the types are reference-related and + reference compatible. We have do do this after stripping + references from FROM. */ + related_p = reference_related_p (to, from); + compatible_p = reference_compatible_p (to, from); + if (lvalue_p && compatible_p) { /* [dcl.init.ref] @@ -3975,15 +3978,20 @@ maybe_handle_implicit_object (ics) member and cv is the cv-qualification on the member function declaration. */ tree t = *ics; + tree reference_type; + + /* The `this' parameter is a pointer to a class type. Make the + implict conversion talk about a reference to that same class + type. */ + reference_type = TREE_TYPE (TREE_TYPE (*ics)); + reference_type = build_reference_type (reference_type); + 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); + t = direct_reference_binding (reference_type, t); *ics = t; } } diff --git a/gcc/testsuite/g++.old-deja/g++.other/covar1.C b/gcc/testsuite/g++.old-deja/g++.other/covar1.C new file mode 100644 index 00000000000..cd19816671a --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/covar1.C @@ -0,0 +1,10 @@ +// Build don't link: +// Origin: Jason Merrill + +struct A { + virtual A& f(); +}; + +struct B: public A { + B& f(); +}; diff --git a/gcc/testsuite/g++.old-deja/g++.other/ref2.C b/gcc/testsuite/g++.old-deja/g++.other/ref2.C new file mode 100644 index 00000000000..5acbcc40bab --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/ref2.C @@ -0,0 +1,15 @@ +// Build don't link: +// Origin: Jason Merrill + + struct A { + int operator * (); + }; + struct B : public A { }; + int operator * (B &); + + int main () + { + B b; + B& br = b; + *br; + } -- 2.30.2