call.c (reference_binding): Tweak.
authorMark Mitchell <mark@codesourcery.com>
Fri, 23 Jul 1999 20:53:54 +0000 (20:53 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Fri, 23 Jul 1999 20:53:54 +0000 (20:53 +0000)
* 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
gcc/cp/call.c
gcc/testsuite/g++.old-deja/g++.other/covar1.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.other/ref2.C [new file with mode: 0644]

index 7844092736807e0437da7177391d89a949e26737..f08254f858c5bf9108775bb9aa2bcdbdf6903013 100644 (file)
@@ -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
index 22f30dcc46b2e682e89bb67c40244402fb23e07d..6e75e94dd0b2ea3a51dca746490642710ef0208f 100644 (file)
@@ -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 (file)
index 0000000..cd19816
--- /dev/null
@@ -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 (file)
index 0000000..5acbcc4
--- /dev/null
@@ -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;
+  }