Commit e0daa2c8 by Jason Merrill Committed by Jakub Jelinek

re PR c++/92705 (ICE: Segmentation fault (in build_new_op_1))

	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.

From-SVN: r278922
parent 5558a0da
2019-12-03 Jason Merrill <jason@redhat.com>
Jakub Jelinek <jakub@redhat.com>
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.
2019-12-03 Jakub Jelinek <jakub@redhat.com> 2019-12-03 Jakub Jelinek <jakub@redhat.com>
PR c++/92695 PR c++/92695
......
...@@ -865,6 +865,22 @@ next_conversion (conversion *conv) ...@@ -865,6 +865,22 @@ next_conversion (conversion *conv)
return conv->u.next; return conv->u.next;
} }
/* Strip to the first ck_user, ck_ambig, ck_list, ck_aggr or ck_identity
encountered. */
static conversion *
strip_standard_conversion (conversion *conv)
{
while (conv
&& conv->kind != ck_user
&& conv->kind != ck_ambig
&& conv->kind != ck_list
&& conv->kind != ck_aggr
&& conv->kind != ck_identity)
conv = next_conversion (conv);
return conv;
}
/* Subroutine of build_aggr_conv: check whether CTOR, a braced-init-list, /* Subroutine of build_aggr_conv: check whether CTOR, a braced-init-list,
is a valid aggregate initializer for array type ATYPE. */ is a valid aggregate initializer for array type ATYPE. */
...@@ -6370,8 +6386,7 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags, ...@@ -6370,8 +6386,7 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags,
conv = cand->convs[0]; conv = cand->convs[0];
if (conv->user_conv_p) if (conv->user_conv_p)
{ {
while (conv->kind != ck_user) conv = strip_standard_conversion (conv);
conv = next_conversion (conv);
arg1 = convert_like (conv, arg1, complain); arg1 = convert_like (conv, arg1, complain);
} }
...@@ -6380,8 +6395,7 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags, ...@@ -6380,8 +6395,7 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags,
conv = cand->convs[1]; conv = cand->convs[1];
if (conv->user_conv_p) if (conv->user_conv_p)
{ {
while (conv->kind != ck_user) conv = strip_standard_conversion (conv);
conv = next_conversion (conv);
arg2 = convert_like (conv, arg2, complain); arg2 = convert_like (conv, arg2, complain);
} }
} }
...@@ -6391,8 +6405,7 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags, ...@@ -6391,8 +6405,7 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags,
conv = cand->convs[2]; conv = cand->convs[2];
if (conv->user_conv_p) if (conv->user_conv_p)
{ {
while (conv->kind != ck_user) conv = strip_standard_conversion (conv);
conv = next_conversion (conv);
arg3 = convert_like (conv, arg3, complain); arg3 = convert_like (conv, arg3, complain);
} }
} }
...@@ -10538,17 +10551,8 @@ compare_ics (conversion *ics1, conversion *ics2) ...@@ -10538,17 +10551,8 @@ compare_ics (conversion *ics1, conversion *ics2)
if (ics1->user_conv_p || ics1->kind == ck_list if (ics1->user_conv_p || ics1->kind == ck_list
|| ics1->kind == ck_aggr || ics2->kind == ck_aggr) || ics1->kind == ck_aggr || ics2->kind == ck_aggr)
{ {
conversion *t1; conversion *t1 = strip_standard_conversion (ics1);
conversion *t2; conversion *t2 = strip_standard_conversion (ics2);
for (t1 = ics1; t1 && t1->kind != ck_user; t1 = next_conversion (t1))
if (t1->kind == ck_ambig || t1->kind == ck_aggr
|| t1->kind == ck_list)
break;
for (t2 = ics2; t2 && t2->kind != ck_user; t2 = next_conversion (t2))
if (t2->kind == ck_ambig || t2->kind == ck_aggr
|| t2->kind == ck_list)
break;
if (!t1 || !t2 || t1->kind != t2->kind) if (!t1 || !t2 || t1->kind != t2->kind)
return 0; return 0;
...@@ -10956,14 +10960,7 @@ compare_ics (conversion *ics1, conversion *ics2) ...@@ -10956,14 +10960,7 @@ compare_ics (conversion *ics1, conversion *ics2)
static tree static tree
source_type (conversion *t) source_type (conversion *t)
{ {
for (;; t = next_conversion (t)) return strip_standard_conversion (t)->type;
{
if (t->kind == ck_user
|| t->kind == ck_ambig
|| t->kind == ck_identity)
return t->type;
}
gcc_unreachable ();
} }
/* Note a warning about preferring WINNER to LOSER. We do this by storing /* Note a warning about preferring WINNER to LOSER. We do this by storing
......
2019-12-03 Jakub Jelinek <jakub@redhat.com> 2019-12-03 Jakub Jelinek <jakub@redhat.com>
PR c++/92705
* g++.dg/conversion/ambig4.C: New test.
PR c++/92695 PR c++/92695
* g++.dg/cpp2a/constexpr-virtual14.C: New test. * g++.dg/cpp2a/constexpr-virtual14.C: New test.
......
// 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" }
}
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