aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>1999-07-23 20:53:54 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1999-07-23 20:53:54 +0000
commitb0385db881d09789d60be06a6bb78246fba4463a (patch)
treeeebcc752477a695b5824974e217275421ba3947b
parented0e65302b574687298c6c1e947799c27e4d0b9b (diff)
downloadgcc-b0385db881d09789d60be06a6bb78246fba4463a.zip
gcc-b0385db881d09789d60be06a6bb78246fba4463a.tar.gz
gcc-b0385db881d09789d60be06a6bb78246fba4463a.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/call.c22
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/covar1.C10
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/ref2.C15
4 files changed, 46 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7844092..f08254f 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+1999-07-23 Mark Mitchell <mark@codesourcery.com>
+
+ * 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 <mark@codesourcery.com>
* pt.c (convert_nontype_argument): Don't call decl_constant_value
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 22f30dc..6e75e94 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 0000000..cd19816
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/covar1.C
@@ -0,0 +1,10 @@
+// Build don't link:
+// Origin: Jason Merrill <jason@cygnus.com>
+
+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 0000000..5acbcc4
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/ref2.C
@@ -0,0 +1,15 @@
+// Build don't link:
+// Origin: Jason Merrill <jason@cygnus.com>
+
+ struct A {
+ int operator * ();
+ };
+ struct B : public A { };
+ int operator * (B &);
+
+ int main ()
+ {
+ B b;
+ B& br = b;
+ *br;
+ }