Because of rank compares, and checks for ck_list, we know that if we
see user_conv_p or ck_list in ics1, we'll also see it in ics2. This
reasoning does not extend to ck_aggr, however, so we might have
ck_aggr conversions starting both ics1 and ics2, which we handle
correctly, or either, which we likely handle by crashing on whatever
path we take depending on whether ck_aggr is in ics1 or ics2.
We crash because, as we search the conversion sequences, we may very
well fail to find what we are looking for, and reach the end of the
sequence, which is unexpected in all paths.
This patch arranges for us to take the same path when ck_aggr is in
ics2 only that we would if it was in ics1 (regardless of ics2), and it
deals with not finding the kind of conversion we look for there.
I've changed the type of the literal constant in the testcase, so as
to hopefully make it well-formed. We'd fail to reject the narrowing
conversion in the original testcase, but that's a separate bug.
for gcc/cp/ChangeLog
PR c++/86218
* call.c (compare_ics): Deal with ck_aggr in either cs.
for gcc/testsuite/ChangeLog
PR c++/86218
* g++.dg/cpp0x/pr86218.C: New.
From-SVN: r268606
+2019-02-07 Alexandre Oliva <aoliva@redhat.com>
+
+ PR c++/86218
+ * call.c (compare_ics): Deal with ck_aggr in either cs.
+
2019-02-06 David Malcolm <dmalcolm@redhat.com>
PR c++/71302
Specifically, we need to do the reference binding comparison at the
end of this function. */
- if (ics1->user_conv_p || ics1->kind == ck_list || ics1->kind == ck_aggr)
+ if (ics1->user_conv_p || ics1->kind == ck_list
+ || ics1->kind == ck_aggr || ics2->kind == ck_aggr)
{
conversion *t1;
conversion *t2;
- for (t1 = ics1; t1->kind != ck_user; t1 = next_conversion (t1))
+ 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->kind != ck_user; t2 = next_conversion (t2))
+ 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->kind != t2->kind)
+ if (!t1 || !t2 || t1->kind != t2->kind)
return 0;
else if (t1->kind == ck_user)
{
+2019-02-07 Alexandre Oliva <aoliva@redhat.com>
+
+ PR c++/86218
+ * g++.dg/cpp0x/pr86218.C: New.
+
2019-02-06 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimization/89225
--- /dev/null
+// { dg-do compile { target c++11 } }
+
+template <int a>
+void f (const char (&)[a]) { }
+void f (int) { }
+template <class...a>
+void
+g ()
+{
+ f ({2u});
+}