Hi! The changed code in build_new_op_1 ICEs on the following testcase, because conv is user_conv_p with kind == ck_ambig, for which next_conversion returns NULL. It seems in other spots where for user_conv_p we are walking the conversion chain we also don't assume there must be ck_user, so this patch just uses the first conv if ck_user is not found (so that the previous diagnostics about ambiguous conversion is emitted).
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2019-11-29 Jakub Jelinek <ja...@redhat.com> PR c++/92705 * call.c (build_new_op_1): For user_conv_p, if there is no ck_user conversion, use the first one. * g++.dg/conversion/ambig4.C: New test. --- gcc/cp/call.c.jj 2019-11-29 12:50:09.664608879 +0100 +++ gcc/cp/call.c 2019-11-29 14:09:54.311718859 +0100 @@ -6370,8 +6370,12 @@ build_new_op_1 (const op_location_t &loc conv = cand->convs[0]; if (conv->user_conv_p) { - while (conv->kind != ck_user) - conv = next_conversion (conv); + for (conversion *t = conv; t; t = next_conversion (t)) + if (t->kind == ck_user) + { + conv = t; + break; + } arg1 = convert_like (conv, arg1, complain); } @@ -6380,8 +6384,12 @@ build_new_op_1 (const op_location_t &loc conv = cand->convs[1]; if (conv->user_conv_p) { - while (conv->kind != ck_user) - conv = next_conversion (conv); + for (conversion *t = conv; t; t = next_conversion (t)) + if (t->kind == ck_user) + { + conv = t; + break; + } arg2 = convert_like (conv, arg2, complain); } } @@ -6391,8 +6399,12 @@ build_new_op_1 (const op_location_t &loc conv = cand->convs[2]; if (conv->user_conv_p) { - while (conv->kind != ck_user) - conv = next_conversion (conv); + for (conversion *t = conv; t; t = next_conversion (t)) + if (t->kind == ck_user) + { + conv = t; + break; + } arg3 = convert_like (conv, arg3, complain); } } --- gcc/testsuite/g++.dg/conversion/ambig4.C.jj 2019-11-29 14:11:35.239183848 +0100 +++ gcc/testsuite/g++.dg/conversion/ambig4.C 2019-11-29 14:11:07.006613238 +0100 @@ -0,0 +1,14 @@ +// PR c++/92705 +// { dg-do compile } + +struct A {}; +struct B {}; +struct C { operator B * (); }; // { dg-message "candidate" } +struct D { operator B * (); }; // { dg-message "candidate" } +struct E : C, D { operator A * (); }; + +void +foo (E e, int B::* pmf) +{ + int i = e->*pmf; // { dg-error "is ambiguous" } +} Jakub