summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2008-04-17 14:01:26 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2008-04-17 14:01:26 +0000
commitfd25a1d05fff30417b7821a77c0d034abc129baa (patch)
tree0f3beacf2dcdb116cafffbd9623593aacb453e4c
parent382e3eba9c7a0ca3e5248885b305b689b3fb067c (diff)
downloadgcc-fd25a1d05fff30417b7821a77c0d034abc129baa.tar.gz
PR c++/35773
* cp/call.c (build_user_type_conversion_1): Represent second step of copy-init with an rvalue conversion. (convert_like_real) [ck_user]: Don't implicitly add it here. * g++.dg/overload/autoptr1.C: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@134398 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/call.c66
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/overload/autoptr1.C29
4 files changed, 73 insertions, 34 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 22a7420523d..3169ba0f366 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2008-04-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/35773
+ * call.c (build_user_type_conversion_1): Represent second step of
+ copy-init with an rvalue conversion.
+ (convert_like_real) [ck_user]: Don't implicitly add it here.
+
2008-04-15 Jakub Jelinek <jakub@redhat.com>
PR c/35751
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 9835c86e3a2..c072a7df77f 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -2634,7 +2634,22 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
flags);
if (cand)
- cand->second_conv = build_identity_conv (totype, NULL_TREE);
+ {
+ cand->second_conv = build_identity_conv (totype, NULL_TREE);
+
+ /* If totype isn't a reference, and LOOKUP_NO_TEMP_BIND isn't
+ set, then this is copy-initialization. In that case, "The
+ result of the call is then used to direct-initialize the
+ object that is the destination of the copy-initialization."
+ [dcl.init]
+
+ We represent this in the conversion sequence with an
+ rvalue conversion, which means a constructor call. */
+ if (TREE_CODE (totype) != REFERENCE_TYPE
+ && !(convflags & LOOKUP_NO_TEMP_BIND))
+ cand->second_conv
+ = build_conv (ck_rvalue, totype, cand->second_conv);
+ }
}
if (conv_fns)
@@ -2686,6 +2701,20 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
0,
/*c_cast_p=*/false, convflags);
+ /* If LOOKUP_NO_TEMP_BIND isn't set, then this is
+ copy-initialization. In that case, "The result of the
+ call is then used to direct-initialize the object that is
+ the destination of the copy-initialization." [dcl.init]
+
+ We represent this in the conversion sequence with an
+ rvalue conversion, which means a constructor call. But
+ don't add a second rvalue conversion if there's already
+ one there. Which there really shouldn't be, but it's
+ harmless since we'd add it here anyway. */
+ if (ics && MAYBE_CLASS_TYPE_P (totype) && ics->kind != ck_rvalue
+ && !(convflags & LOOKUP_NO_TEMP_BIND))
+ ics = build_conv (ck_rvalue, totype, ics);
+
cand->second_conv = ics;
if (!ics)
@@ -4425,38 +4454,6 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
if (DECL_CONSTRUCTOR_P (convfn))
expr = build_cplus_new (totype, expr);
- /* The result of the call is then used to direct-initialize the object
- that is the destination of the copy-initialization. [dcl.init]
-
- Note that this step is not reflected in the conversion sequence;
- it affects the semantics when we actually perform the
- conversion, but is not considered during overload resolution.
-
- If the target is a class, that means call a ctor. */
- if (MAYBE_CLASS_TYPE_P (totype)
- && (inner >= 0 || !lvalue_p (expr)))
- {
- expr = (build_temp
- (expr, totype,
- /* Core issue 84, now a DR, says that we don't
- allow UDCs for these args (which deliberately
- breaks copy-init of an auto_ptr<Base> from an
- auto_ptr<Derived>). */
- LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING|LOOKUP_NO_CONVERSION,
- &diagnostic_fn));
-
- if (diagnostic_fn && (complain & tf_error))
- {
- if (fn)
- diagnostic_fn
- (" initializing argument %P of %qD from result of %qD",
- argnum, fn, convfn);
- else
- diagnostic_fn
- (" initializing temporary from result of %qD", convfn);
- }
- expr = build_cplus_new (totype, expr);
- }
return expr;
}
case ck_identity:
@@ -4518,7 +4515,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
flags = LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING;
if (convs->user_conv_p)
/* This conversion is being done in the context of a user-defined
- conversion, so don't allow any more. */
+ conversion (i.e. the second step of copy-initialization), so
+ don't allow any more. */
flags |= LOOKUP_NO_CONVERSION;
expr = build_temp (expr, totype, flags, &diagnostic_fn);
if (diagnostic_fn && fn)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4b66c95efb5..63650dc3a8c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2008-04-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/35773
+ * g++.dg/overload/autoptr1.C: New.
+
2008-04-17 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/alignment4.adb: New test.
diff --git a/gcc/testsuite/g++.dg/overload/autoptr1.C b/gcc/testsuite/g++.dg/overload/autoptr1.C
new file mode 100644
index 00000000000..fc81083500e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/overload/autoptr1.C
@@ -0,0 +1,29 @@
+// PR c++/35773
+
+template< typename T >
+class auto_ptr
+{
+ struct auto_ptr_ref { };
+public:
+ auto_ptr(auto_ptr&);
+ auto_ptr(auto_ptr_ref);
+
+ operator auto_ptr_ref();
+};
+
+template< typename T >
+class reference_wrapper
+{
+public:
+ reference_wrapper(T& t);
+ operator T& () const;
+};
+
+struct X { };
+
+void f(auto_ptr< X >);
+
+void g(reference_wrapper< auto_ptr< X > > r)
+{
+ f(r);
+}