g++-10.0.0-alpha20191124 snapshot (r278660) ICEs when compiling the following testcase reduced from test/SemaCXX/builtin-ptrtomember-overload-1.cpp from the clang 9.0.0 test suite: struct A {}; struct E {}; struct R { operator E*(); }; struct S { operator E*(); }; struct B1 : R, S { operator A*(); }; void foo1(B1 b1, int E::* pmf) { int i = b1->*pmf; } % g++-10.0.0-alpha20191124 -c gmnbcjli.cpp gmnbcjli.cpp: In function 'void foo1(B1, int E::*)': gmnbcjli.cpp:17:22: internal compiler error: Segmentation fault 17 | int i = b1->*pmf; | ^~~ 0xf36080 crash_signal /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/toplev.c:328 0x839d0e build_new_op_1 /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/call.c:6375 0x83a33a build_new_op(op_location_t const&, tree_code, int, tree_node*, tree_node*, tree_node*, tree_node**, int) /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/call.c:6500 0x9f8dd1 build_x_binary_op(op_location_t const&, tree_code, tree_node*, tree_code, tree_node*, tree_code, tree_node**, int) /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/typeck.c:4223 0x92d178 cp_parser_binary_expression /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:9645 0x92e026 cp_parser_assignment_expression /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:9780 0x92d869 cp_parser_constant_expression /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:10074 0x92dfcb cp_parser_initializer_clause /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:23032 0x9320b7 cp_parser_initializer /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:22970 0x957b5b cp_parser_init_declarator /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:20678 0x93aa52 cp_parser_simple_declaration /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:13624 0x93c87f cp_parser_declaration_statement /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:13055 0x93d3c4 cp_parser_statement /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:11380 0x93e3c5 cp_parser_statement_seq_opt /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:11742 0x93e492 cp_parser_compound_statement /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:11696 0x953e74 cp_parser_function_body /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:22876 0x953e74 cp_parser_ctor_initializer_opt_and_function_body /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:22927 0x957005 cp_parser_function_definition_after_declarator /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:28597 0x957fe4 cp_parser_function_definition_from_specifiers_and_declarator /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:28513 0x957fe4 cp_parser_init_declarator /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:20505
Started with r277864. This isn't error-recovery, there is no error printed before it ICEs. Slightly shortened: struct A {}; struct B {}; struct C { operator B*(); }; struct D { operator B*(); }; struct E : C, D { operator A*(); }; void foo(E e, int B::* pmf) { int i = e->*pmf; }
The ICE is because conv is ck_ambig with user_conv_p set. Looking at other conv->user_conv_p tests, e.g. reference_binding does: if (conv->user_conv_p) { ... for (conversion *t = conv; t; t = next_conversion (t)) if (t->kind == ck_user && DECL_CONV_FN_P (t->cand->fn)) { and doesn't expect that user_conv_p implies that ck_user will appear. The following patch restores the previous diagnostics on the testcase, but I'm afraid I have no idea what is right. If ck_ambig with user_conv_p set is right, then it itself isn't ck_user and next_conversion on it is NULL. --- gcc/cp/call.c.jj 2019-11-28 18:58:55.671297387 +0100 +++ gcc/cp/call.c 2019-11-29 12:33:04.033386816 +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); } }
Though, previously the convert_like calls were done no matter what the conversion is, so with the above patch maybe after the if (conv->user_conv_p) ... stmts, with whatever the conv is. Not sure if it makes a difference for anything.
Author: jakub Date: Tue Dec 3 08:20:18 2019 New Revision: 278922 URL: https://gcc.gnu.org/viewcvs?rev=278922&root=gcc&view=rev Log: PR c++/92705 * call.c (strip_standard_conversion): New function. (build_new_op_1): Use it for user_conv_p. (compare_ics): Likewise. (source_type): Likewise. * g++.dg/conversion/ambig4.C: New test. Added: trunk/gcc/testsuite/g++.dg/conversion/ambig4.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/call.c trunk/gcc/testsuite/ChangeLog
Fixed.