call.c (convert_like_real): Add extra semantics to INNER parameter.
authorNathan Sidwell <nathan@codesourcery.com>
Mon, 12 Mar 2001 15:43:52 +0000 (15:43 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Mon, 12 Mar 2001 15:43:52 +0000 (15:43 +0000)
cp:
* call.c (convert_like_real): Add extra semantics to INNER
parameter. Don't convert to temporary if a user conversion
gives us an lvalue that we're about to bind to a reference.
Set INNER to indicate pending reference binding on recursive
calls.
testsuite:
* g++.old-deja/g++.other/ref4.C: New test.

From-SVN: r40415

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.old-deja/g++.other/ref4.C [new file with mode: 0644]

index 3f0fa1926073ad6de7e63eff858eb9a41232311a..46871a9c2279fd345fd634d568684ac892fad248 100644 (file)
@@ -1,3 +1,11 @@
+2001-03-12  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * call.c (convert_like_real): Add extra semantics to INNER
+       parameter. Don't convert to temporary if a user conversion
+       gives us an lvalue that we're about to bind to a reference.
+       Set INNER to indicate pending reference binding on recursive
+       calls.
+
 2001-03-10  Neil Booth  <neil@daikokuya.demon.co.uk>
 
        * cp/lex.c: Delete duplicate pending_lang_change.
index 69c58db2d43e7787c526543a2bd520403c94d355..13827c9d1c48b6d896b19c6174b84454667870cc 100644 (file)
@@ -3676,7 +3676,8 @@ enforce_access (basetype_path, decl)
 /* Perform the conversions in CONVS on the expression EXPR. 
    FN and ARGNUM are used for diagnostics.  ARGNUM is zero based, -1
    indicates the `this' argument of a method.  INNER is non-zero when
-   being called to continue a conversion chain. */
+   being called to continue a conversion chain. It is negative when a
+   reference binding will be applied, positive otherwise. */
 
 static tree
 convert_like_real (convs, expr, fn, argnum, inner)
@@ -3755,7 +3756,8 @@ convert_like_real (convs, expr, fn, argnum, inner)
           conversion, but is not considered during overload resolution.
 
           If the target is a class, that means call a ctor.  */
-       if (IS_AGGR_TYPE (totype))
+       if (IS_AGGR_TYPE (totype)
+           && (inner >= 0 || !real_lvalue_p (expr)))
          {
            savew = warningcount, savee = errorcount;
            expr = build_new_method_call
@@ -3804,7 +3806,8 @@ convert_like_real (convs, expr, fn, argnum, inner)
       break;
     };
 
-  expr = convert_like_real (TREE_OPERAND (convs, 0), expr, fn, argnum, 1);
+  expr = convert_like_real (TREE_OPERAND (convs, 0), expr, fn, argnum,
+                            TREE_CODE (convs) == REF_BIND ? -1 : 1);
   if (expr == error_mark_node)
     return error_mark_node;
 
index ab380c420058735aa2a9e46edc28333e917f2b09..c86f7502246cd64b3af521c0b6c3f1ea1a3667a0 100644 (file)
@@ -1,3 +1,7 @@
+2001-03-12  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * g++.old-deja/g++.other/ref4.C: New test.
+
 2001-03-11  Nicola Pero <n.pero@mi.flashnet.it>
 
        * objc/execute/va_method.m: Added.
diff --git a/gcc/testsuite/g++.old-deja/g++.other/ref4.C b/gcc/testsuite/g++.old-deja/g++.other/ref4.C
new file mode 100644 (file)
index 0000000..c3535d0
--- /dev/null
@@ -0,0 +1,28 @@
+// Build don't link:
+
+// Copyright (C) 2001 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 27 Feb 2001 <nathan@codesourcery.com>
+
+// Bug 2117. A conversion op to reference type created a temporary, even
+// when bound to another reference.
+
+struct Abstract
+{
+  virtual void Foo () = 0;
+};
+
+struct Proxy
+{
+  operator Abstract & ();
+  Abstract &Convert ();
+};
+
+void Baz (Abstract &);
+
+void Foo ()
+{
+  Proxy proxy;
+  
+  Baz (proxy);
+  Baz (proxy.Convert ());
+}