aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2001-03-12 15:43:52 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2001-03-12 15:43:52 +0000
commit78fe06c24507d3f70c80477816689dafc2c2c354 (patch)
treee9141241cb2c5fbfb50f590b2f67be25fb888ccf /gcc
parent99560e26f8eb8b58250d0793c928826a38f06928 (diff)
downloadgcc-78fe06c24507d3f70c80477816689dafc2c2c354.zip
gcc-78fe06c24507d3f70c80477816689dafc2c2c354.tar.gz
gcc-78fe06c24507d3f70c80477816689dafc2c2c354.tar.bz2
call.c (convert_like_real): Add extra semantics to INNER parameter.
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/call.c9
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/ref4.C28
4 files changed, 46 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 3f0fa19..46871a9 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 69c58db..13827c9 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ab380c4..c86f750 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..c3535d0
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/ref4.C
@@ -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 ());
+}