From: Jason Merrill Date: Fri, 9 May 2014 18:15:57 +0000 (-0400) Subject: re PR c++/32019 (Conditional operator ?: and ambiguous convertions) X-Git-Tag: releases/gcc-5.1.0~7667 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5f901ccf18953b699bd290a4a169e2b7c7aa870a;p=thirdparty%2Fgcc.git re PR c++/32019 (Conditional operator ?: and ambiguous convertions) PR c++/32019 * call.c (build_conditional_expr_1): Improve ambiguity diagnostic. PR c++/54348 * call.c (build_conditional_expr_1): If overload resolution finds no match, just say "different types". From-SVN: r210282 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 232ceec6ed1a..6bddd4974f0a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,12 @@ 2014-05-09 Jason Merrill + PR c++/54348 + * call.c (build_conditional_expr_1): If overload resolution finds + no match, just say "different types". + + PR c++/32019 + * call.c (build_conditional_expr_1): Improve ambiguity diagnostic. + PR c++/22434 * call.c (build_conditional_expr_1): Don't try to pool cv-quals if we didn't find a conversion. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 691e9e3ce90a..cff7ef32339d 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4710,8 +4710,16 @@ build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3, || (conv3 && conv3->kind == ck_ambig)) { if (complain & tf_error) - error_at (loc, "operands to ?: have different types %qT and %qT", - arg2_type, arg3_type); + { + error_at (loc, "operands to ?: have different types %qT and %qT", + arg2_type, arg3_type); + if (conv2 && !conv2->bad_p && conv3 && !conv3->bad_p) + inform (loc, " and each type can be converted to the other"); + else if (conv2 && conv2->kind == ck_ambig) + convert_like (conv2, arg2, complain); + else + convert_like (conv3, arg3, complain); + } result = error_mark_node; } else if (conv2 && !conv2->bad_p) @@ -4818,10 +4826,8 @@ build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3, if (!any_viable_p) { if (complain & tf_error) - { - op_error (loc, COND_EXPR, NOP_EXPR, arg1, arg2, arg3, FALSE); - print_z_candidates (loc, candidates); - } + error_at (loc, "operands to ?: have different types %qT and %qT", + arg2_type, arg3_type); return error_mark_node; } cand = tourney (candidates, complain); diff --git a/gcc/testsuite/g++.dg/cpp0x/explicit3.C b/gcc/testsuite/g++.dg/cpp0x/explicit3.C index 678076c8e412..6318ade2c0e1 100644 --- a/gcc/testsuite/g++.dg/cpp0x/explicit3.C +++ b/gcc/testsuite/g++.dg/cpp0x/explicit3.C @@ -45,6 +45,6 @@ int main() f(a); // { dg-error "" } B b2 = { a }; // { dg-error "" } a + true; // { dg-error "5:no match" } - b ? a : true; // { dg-error "5:no match" } - a ? a : true; // { dg-error "5:no match" } + b ? a : true; // { dg-error "5:?:" } + a ? a : true; // { dg-error "5:?:" } } diff --git a/gcc/testsuite/g++.dg/expr/cond10.C b/gcc/testsuite/g++.dg/expr/cond10.C new file mode 100644 index 000000000000..892576fa8b82 --- /dev/null +++ b/gcc/testsuite/g++.dg/expr/cond10.C @@ -0,0 +1,17 @@ +// PR c++/32019 + +struct C +{ + C(const char *); + operator const char *(); +}; + +extern C c; +extern const char * s; + +void +foo (bool b) +{ + b ? c : s; // { dg-error "?:" } + // { dg-message "convert" "" { target *-*-* } 15 } +} diff --git a/gcc/testsuite/g++.dg/expr/cond11.C b/gcc/testsuite/g++.dg/expr/cond11.C new file mode 100644 index 000000000000..7bd122ddac5e --- /dev/null +++ b/gcc/testsuite/g++.dg/expr/cond11.C @@ -0,0 +1,20 @@ +struct A; +struct C +{ + operator A(); +}; + +struct A +{ + A(C); +}; + +extern A a; +extern C c; + +void +foo (bool b) +{ + b ? c : a; // { dg-error "?:" } + // { dg-message "ambiguous" "" { target *-*-* } 18 } +} diff --git a/gcc/testsuite/g++.dg/expr/cond13.C b/gcc/testsuite/g++.dg/expr/cond13.C new file mode 100644 index 000000000000..90ae904a5d61 --- /dev/null +++ b/gcc/testsuite/g++.dg/expr/cond13.C @@ -0,0 +1,9 @@ +// PR c++/54348 + +struct A {} a; +struct B {} b; + +void f() +{ + false ? a : b; // { dg-error "different types" } +} diff --git a/gcc/testsuite/g++.dg/parse/crash41.C b/gcc/testsuite/g++.dg/parse/crash41.C index 746dbbca8a1d..c14fbadff9f8 100644 --- a/gcc/testsuite/g++.dg/parse/crash41.C +++ b/gcc/testsuite/g++.dg/parse/crash41.C @@ -5,4 +5,4 @@ struct A A(int)(); // { dg-error "declared" } }; -template void foo(bool b, A a) { b ? a : 0; } // { dg-error "no match" } +template void foo(bool b, A a) { b ? a : 0; } // { dg-error "?:" }