Commit 929a0122 by Jason Merrill Committed by Jason Merrill

PR c++/84906 - silent wrong code with ambiguous conversion.

	* call.c (build_user_type_conversion_1): Set need_temporary_p on
	ambiguous conversion.
	(convert_like_real): Check it.

From-SVN: r258603
parent 7293e3f5
2018-03-16 Jason Merrill <jason@redhat.com> 2018-03-16 Jason Merrill <jason@redhat.com>
PR c++/84906 - silent wrong code with ambiguous conversion.
* call.c (build_user_type_conversion_1): Set need_temporary_p on
ambiguous conversion.
(convert_like_real): Check it.
PR c++/83937 - wrong C++17 handling of init-list ctor argument. PR c++/83937 - wrong C++17 handling of init-list ctor argument.
* call.c (build_special_member_call): Don't convert an init-list * call.c (build_special_member_call): Don't convert an init-list
argument directly to the class type. argument directly to the class type.
......
...@@ -93,7 +93,8 @@ struct conversion { ...@@ -93,7 +93,8 @@ struct conversion {
BOOL_BITFIELD bad_p : 1; BOOL_BITFIELD bad_p : 1;
/* If KIND is ck_ref_bind ck_base_conv, true to indicate that a /* If KIND is ck_ref_bind ck_base_conv, true to indicate that a
temporary should be created to hold the result of the temporary should be created to hold the result of the
conversion. */ conversion. If KIND is ck_ambig, true if the context is
copy-initialization. */
BOOL_BITFIELD need_temporary_p : 1; BOOL_BITFIELD need_temporary_p : 1;
/* If KIND is ck_ptr or ck_pmem, true to indicate that a conversion /* If KIND is ck_ptr or ck_pmem, true to indicate that a conversion
from a pointer-to-derived to pointer-to-base is being performed. */ from a pointer-to-derived to pointer-to-base is being performed. */
...@@ -3943,6 +3944,8 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags, ...@@ -3943,6 +3944,8 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags,
cand->second_conv->user_conv_p = true; cand->second_conv->user_conv_p = true;
if (!any_strictly_viable (candidates)) if (!any_strictly_viable (candidates))
cand->second_conv->bad_p = true; cand->second_conv->bad_p = true;
if (flags & LOOKUP_ONLYCONVERTING)
cand->second_conv->need_temporary_p = true;
/* If there are viable candidates, don't set ICS_BAD_FLAG; an /* If there are viable candidates, don't set ICS_BAD_FLAG; an
ambiguous conversion is no worse than another user-defined ambiguous conversion is no worse than another user-defined
conversion. */ conversion. */
...@@ -6834,8 +6837,10 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, ...@@ -6834,8 +6837,10 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
if (complain & tf_error) if (complain & tf_error)
{ {
/* Call build_user_type_conversion again for the error. */ /* Call build_user_type_conversion again for the error. */
build_user_type_conversion (totype, convs->u.expr, LOOKUP_IMPLICIT, int flags = (convs->need_temporary_p
complain); ? LOOKUP_IMPLICIT : LOOKUP_NORMAL);
build_user_type_conversion (totype, convs->u.expr, flags, complain);
gcc_assert (seen_error ());
if (fn) if (fn)
inform (DECL_SOURCE_LOCATION (fn), inform (DECL_SOURCE_LOCATION (fn),
" initializing argument %P of %qD", argnum, fn); " initializing argument %P of %qD", argnum, fn);
......
// PR c++/84906
// { dg-do compile { target c++14 } }
extern "C" int puts(const char*);
struct aa {
operator auto() {
puts("auto");
return false;
}
explicit operator bool() {
puts("bool");
return true;
}
};
int main() {
aa x;
if (x) // { dg-error "ambiguous" }
puts("here");
else
puts("there");
}
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