diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e4400873320..e5d0b4c4a5c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,13 @@ 2011-12-19 Jason Merrill + 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 parm in list-initialization unless the argument is an init-list. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 3e6db511923..29aed980ee1 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -1956,17 +1956,17 @@ add_function_candidate (struct z_candidate **candidates, 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))) { - lflags |= LOOKUP_COPY_PARM; + if (!(flags & LOOKUP_ONLYCONVERTING)) + lflags |= LOOKUP_COPY_PARM; /* We allow user-defined conversions within init-lists, but don't list-initialize the copy parm, as that would mean 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)) lflags |= LOOKUP_NO_CONVERSION; } @@ -3344,9 +3344,8 @@ add_list_candidates (tree fns, tree first_arg, gcc_assert (*candidates == NULL); - /* For list-initialization we consider explicit constructors, but - give an error if one is selected. */ - flags &= ~LOOKUP_ONLYCONVERTING; + /* We're looking for a ctor for list-initialization. */ + flags |= LOOKUP_LIST_INIT_CTOR; /* And we don't allow narrowing conversions. We also use this flag to avoid the copy constructor call for copy-list-initialization. */ flags |= LOOKUP_NO_NARROWING; @@ -3374,8 +3373,6 @@ add_list_candidates (tree fns, tree first_arg, flags &= ~LOOKUP_LIST_ONLY; /* We allow more user-defined conversions within an init-list. */ flags &= ~LOOKUP_NO_CONVERSION; - /* But not for the copy ctor. */ - flags |= LOOKUP_NO_COPY_CTOR_CONVERSION; add_candidates (fns, first_arg, args, NULL_TREE, explicit_targs, template_only, conversion_path, @@ -4801,7 +4798,11 @@ add_candidates (tree fns, tree first_arg, const VEC(tree,gc) *args, if (DECL_CONSTRUCTOR_P (fn)) { 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 { diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 42a9ced641a..633b6b43171 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4384,11 +4384,10 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG }; #define LOOKUP_PREFER_RVALUE (LOOKUP_HIDDEN << 1) /* We're inside an init-list, so narrowing conversions are ill-formed. */ #define LOOKUP_NO_NARROWING (LOOKUP_PREFER_RVALUE << 1) -/* Avoid user-defined conversions for the first parameter of a copy - constructor (or move constructor). */ -#define LOOKUP_NO_COPY_CTOR_CONVERSION (LOOKUP_NO_NARROWING << 1) +/* We're looking up a constructor for list-initialization. */ +#define LOOKUP_LIST_INIT_CTOR (LOOKUP_NO_NARROWING << 1) /* 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. */ #define LOOKUP_LIST_ONLY (LOOKUP_COPY_PARM << 1) /* Return after determining which function to call and checking access. diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist64.C b/gcc/testsuite/g++.dg/cpp0x/initlist64.C index 337e89b3568..bcf1658074d 100644 --- a/gcc/testsuite/g++.dg/cpp0x/initlist64.C +++ b/gcc/testsuite/g++.dg/cpp0x/initlist64.C @@ -22,7 +22,7 @@ X aa = Y(); X b{ Y() }; X bb(Y()); -X c = { Z() }; // { dg-error "" "" { xfail *-*-* } } +X c = { Z() }; // { dg-error "" } X cc = Z(); // { dg-error "" } X d{ Z() };