mirror of git://gcc.gnu.org/git/gcc.git
re PR c++/35773 (auto_ptr references don't convert)
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.
From-SVN: r134398
This commit is contained in:
parent
ec2e9a15a8
commit
46225e2688
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
Loading…
Reference in New Issue