Commit 11c71a22 by Jason Merrill Committed by Jason Merrill

re PR c++/51553 (brace initialization and conversion operators)

	PR c++/51553
	* cp-tree.h (LOOKUP_LIST_INIT_CTOR): Rename from
	LOOKUP_NO_COPY_CTOR_CONVERSION.
	(add_list_candidates): Set it earlier.
	(add_candidates): Don't check explicit on ctors when it's set.
	(add_function_candidate): Check it even when LOOKUP_ONLYCONVERTING
	is set.

From-SVN: r182496
parent 00ef7059
2011-12-19 Jason Merrill <jason@redhat.com> 2011-12-19 Jason Merrill <jason@redhat.com>
PR c++/51553 PR c++/51553
* cp-tree.h (LOOKUP_LIST_INIT_CTOR): Rename from
LOOKUP_NO_COPY_CTOR_CONVERSION.
(add_list_candidates): Set it earlier.
(add_candidates): Don't check explicit on ctors when it's set.
(add_function_candidate): Check it even when LOOKUP_ONLYCONVERTING
is set.
PR c++/51553
* call.c (add_function_candidate): Allow conversions for the copy * call.c (add_function_candidate): Allow conversions for the copy
parm in list-initialization unless the argument is an init-list. parm in list-initialization unless the argument is an init-list.
......
...@@ -1956,17 +1956,17 @@ add_function_candidate (struct z_candidate **candidates, ...@@ -1956,17 +1956,17 @@ add_function_candidate (struct z_candidate **candidates,
to handle move constructors and template constructors as well; to handle move constructors and template constructors as well;
the standardese should soon be updated similarly. */ the standardese should soon be updated similarly. */
if (ctype && i == 0 && (len-skip == 1) if (ctype && i == 0 && (len-skip == 1)
&& !(flags & LOOKUP_ONLYCONVERTING)
&& DECL_CONSTRUCTOR_P (fn) && DECL_CONSTRUCTOR_P (fn)
&& parmtype != error_mark_node && parmtype != error_mark_node
&& (same_type_ignoring_top_level_qualifiers_p && (same_type_ignoring_top_level_qualifiers_p
(non_reference (parmtype), ctype))) (non_reference (parmtype), ctype)))
{ {
lflags |= LOOKUP_COPY_PARM; if (!(flags & LOOKUP_ONLYCONVERTING))
lflags |= LOOKUP_COPY_PARM;
/* We allow user-defined conversions within init-lists, but /* We allow user-defined conversions within init-lists, but
don't list-initialize the copy parm, as that would mean don't list-initialize the copy parm, as that would mean
using two levels of braces for the same type. */ using two levels of braces for the same type. */
if ((flags & LOOKUP_NO_COPY_CTOR_CONVERSION) if ((flags & LOOKUP_LIST_INIT_CTOR)
&& BRACE_ENCLOSED_INITIALIZER_P (arg)) && BRACE_ENCLOSED_INITIALIZER_P (arg))
lflags |= LOOKUP_NO_CONVERSION; lflags |= LOOKUP_NO_CONVERSION;
} }
...@@ -3344,9 +3344,8 @@ add_list_candidates (tree fns, tree first_arg, ...@@ -3344,9 +3344,8 @@ add_list_candidates (tree fns, tree first_arg,
gcc_assert (*candidates == NULL); gcc_assert (*candidates == NULL);
/* For list-initialization we consider explicit constructors, but /* We're looking for a ctor for list-initialization. */
give an error if one is selected. */ flags |= LOOKUP_LIST_INIT_CTOR;
flags &= ~LOOKUP_ONLYCONVERTING;
/* And we don't allow narrowing conversions. We also use this flag to /* And we don't allow narrowing conversions. We also use this flag to
avoid the copy constructor call for copy-list-initialization. */ avoid the copy constructor call for copy-list-initialization. */
flags |= LOOKUP_NO_NARROWING; flags |= LOOKUP_NO_NARROWING;
...@@ -3374,8 +3373,6 @@ add_list_candidates (tree fns, tree first_arg, ...@@ -3374,8 +3373,6 @@ add_list_candidates (tree fns, tree first_arg,
flags &= ~LOOKUP_LIST_ONLY; flags &= ~LOOKUP_LIST_ONLY;
/* We allow more user-defined conversions within an init-list. */ /* We allow more user-defined conversions within an init-list. */
flags &= ~LOOKUP_NO_CONVERSION; flags &= ~LOOKUP_NO_CONVERSION;
/* But not for the copy ctor. */
flags |= LOOKUP_NO_COPY_CTOR_CONVERSION;
add_candidates (fns, first_arg, args, NULL_TREE, add_candidates (fns, first_arg, args, NULL_TREE,
explicit_targs, template_only, conversion_path, explicit_targs, template_only, conversion_path,
...@@ -4801,7 +4798,11 @@ add_candidates (tree fns, tree first_arg, const VEC(tree,gc) *args, ...@@ -4801,7 +4798,11 @@ add_candidates (tree fns, tree first_arg, const VEC(tree,gc) *args,
if (DECL_CONSTRUCTOR_P (fn)) if (DECL_CONSTRUCTOR_P (fn))
{ {
check_list_ctor = !!(flags & LOOKUP_LIST_ONLY); check_list_ctor = !!(flags & LOOKUP_LIST_ONLY);
check_converting = !!(flags & LOOKUP_ONLYCONVERTING); /* For list-initialization we consider explicit constructors
and complain if one is chosen. */
check_converting
= ((flags & (LOOKUP_ONLYCONVERTING|LOOKUP_LIST_INIT_CTOR))
== LOOKUP_ONLYCONVERTING);
} }
else else
{ {
......
...@@ -4384,11 +4384,10 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG }; ...@@ -4384,11 +4384,10 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG };
#define LOOKUP_PREFER_RVALUE (LOOKUP_HIDDEN << 1) #define LOOKUP_PREFER_RVALUE (LOOKUP_HIDDEN << 1)
/* We're inside an init-list, so narrowing conversions are ill-formed. */ /* We're inside an init-list, so narrowing conversions are ill-formed. */
#define LOOKUP_NO_NARROWING (LOOKUP_PREFER_RVALUE << 1) #define LOOKUP_NO_NARROWING (LOOKUP_PREFER_RVALUE << 1)
/* Avoid user-defined conversions for the first parameter of a copy /* We're looking up a constructor for list-initialization. */
constructor (or move constructor). */ #define LOOKUP_LIST_INIT_CTOR (LOOKUP_NO_NARROWING << 1)
#define LOOKUP_NO_COPY_CTOR_CONVERSION (LOOKUP_NO_NARROWING << 1)
/* This is the first parameter of a copy constructor. */ /* This is the first parameter of a copy constructor. */
#define LOOKUP_COPY_PARM (LOOKUP_NO_COPY_CTOR_CONVERSION << 1) #define LOOKUP_COPY_PARM (LOOKUP_LIST_INIT_CTOR << 1)
/* We only want to consider list constructors. */ /* We only want to consider list constructors. */
#define LOOKUP_LIST_ONLY (LOOKUP_COPY_PARM << 1) #define LOOKUP_LIST_ONLY (LOOKUP_COPY_PARM << 1)
/* Return after determining which function to call and checking access. /* Return after determining which function to call and checking access.
......
...@@ -22,7 +22,7 @@ X aa = Y(); ...@@ -22,7 +22,7 @@ X aa = Y();
X b{ Y() }; X b{ Y() };
X bb(Y()); X bb(Y());
X c = { Z() }; // { dg-error "" "" { xfail *-*-* } } X c = { Z() }; // { dg-error "" }
X cc = Z(); // { dg-error "" } X cc = Z(); // { dg-error "" }
X d{ Z() }; X d{ Z() };
......
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