Commit cef62ad4 by Jason Merrill Committed by Jason Merrill

call.c (add_function_candidate): Set LOOKUP_COPY_PARM for any constructor called…

call.c (add_function_candidate): Set LOOKUP_COPY_PARM for any constructor called with a single argument that...

	* call.c (add_function_candidate): Set LOOKUP_COPY_PARM for any
	constructor called with a single argument that takes a reference
	to the constructor's class.
	(BAD_CONVERSION_RANK): New.
	(compare_ics): Use it to compare bad ICSes.

From-SVN: r161443
parent d9816849
2010-06-26 Jason Merrill <jason@redhat.com>
* call.c (add_function_candidate): Set LOOKUP_COPY_PARM for any
constructor called with a single argument that takes a reference
to the constructor's class.
(BAD_CONVERSION_RANK): New.
(compare_ics): Use it to compare bad ICSes.
2010-06-25 Joseph Myers <joseph@codesourcery.com>
* lang-specs.h: Remove +e handling.
......
......@@ -122,6 +122,11 @@ struct conversion {
: (NODE)->user_conv_p ? cr_user \
: (NODE)->rank)
#define BAD_CONVERSION_RANK(NODE) \
((NODE)->ellipsis_p ? cr_ellipsis \
: (NODE)->user_conv_p ? cr_user \
: (NODE)->rank)
static struct obstack conversion_obstack;
static bool conversion_obstack_initialized;
......@@ -1386,9 +1391,12 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
conversion operator). */
flags |= LOOKUP_NO_TEMP_BIND;
/* Temporaries are copy-initialized, except for this hack to allow
explicit conversion ops to the copy ctor. See also
add_function_candidate. */
/* Core issue 899: When [copy-]initializing a temporary to be bound
to the first parameter of a copy constructor (12.8) called with
a single argument in the context of direct-initialization,
explicit conversion functions are also considered.
So don't set LOOKUP_ONLYCONVERTING in that case. */
if (!(flags & LOOKUP_COPY_PARM))
flags |= LOOKUP_ONLYCONVERTING;
......@@ -1618,6 +1626,8 @@ add_function_candidate (struct z_candidate **candidates,
tree parmtype = TREE_VALUE (parmnode);
int lflags = flags;
parmnode = TREE_CHAIN (parmnode);
/* The type of the implicit object parameter ('this') for
overload resolution is not always the same as for the
function itself; conversion functions are considered to
......@@ -1634,13 +1644,25 @@ add_function_candidate (struct z_candidate **candidates,
parmtype = build_pointer_type (parmtype);
}
if (ctype && i == 0 && DECL_COPY_CONSTRUCTOR_P (fn)
&& (len-skip == 1))
/* Core issue 899: When [copy-]initializing a temporary to be bound
to the first parameter of a copy constructor (12.8) called with
a single argument in the context of direct-initialization,
explicit conversion functions are also considered.
So set LOOKUP_COPY_PARM to let reference_binding know that
it's being called in that context. We generalize the above
to handle move constructors and template constructors as well;
the standardese should soon be updated similarly. */
if (ctype && i == 0 && (len-skip == 1)
&& !(flags & LOOKUP_ONLYCONVERTING)
&& DECL_CONSTRUCTOR_P (fn)
&& parmtype != error_mark_node
&& (same_type_ignoring_top_level_qualifiers_p
(non_reference (parmtype), ctype)))
{
/* Hack: Direct-initialize copy parm (i.e. suppress
LOOKUP_ONLYCONVERTING) to make explicit conversion ops
work. See also reference_binding. */
lflags |= LOOKUP_COPY_PARM;
/* We allow user-defined conversions within init-lists, but
not for the copy constructor. */
if (flags & LOOKUP_NO_COPY_CTOR_CONVERSION)
lflags |= LOOKUP_NO_CONVERSION;
}
......@@ -1668,9 +1690,6 @@ add_function_candidate (struct z_candidate **candidates,
if (t->bad_p)
viable = -1;
if (parmnode)
parmnode = TREE_CHAIN (parmnode);
}
out:
......@@ -6741,14 +6760,16 @@ compare_ics (conversion *ics1, conversion *ics2)
if (rank1 == cr_bad)
{
/* XXX Isn't this an extension? */
/* Both ICS are bad. We try to make a decision based on what
would have happened if they'd been good. */
if (ics1->user_conv_p > ics2->user_conv_p
|| ics1->rank > ics2->rank)
/* Both ICS are bad. We try to make a decision based on what would
have happened if they'd been good. This is not an extension,
we'll still give an error when we build up the call; this just
helps us give a more helpful error message. */
rank1 = BAD_CONVERSION_RANK (ics1);
rank2 = BAD_CONVERSION_RANK (ics2);
if (rank1 > rank2)
return -1;
else if (ics1->user_conv_p < ics2->user_conv_p
|| ics1->rank < ics2->rank)
else if (rank1 < rank2)
return 1;
/* We couldn't make up our minds; try to figure it out below. */
......
2010-06-26 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/explicit5.C: New.
2010-06-26 Richard Guenther <rguenther@suse.de>
PR tree-optimization/44393
......
// test for extension of DR 899 to handle template ctors
// { dg-options "-std=c++0x" }
// { dg-do run }
int r = 1;
struct C {
C() { }
template <class T = int> C(C&, T = 0) { r = 0; }
};
C c;
struct A
{
explicit operator C&() const { return c; }
};
int main()
{
A a;
C c2 (a);
return r;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment