aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2019-02-07 07:50:42 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2019-02-07 07:50:42 +0000
commitdc51dece7ae902317e9131e153ef53d7bc09c564 (patch)
tree78f49ebb2065ad6209cb9a5f4a12ee47162ef1c8
parent18591d3ee7c0e22c3f81340fbc0a54d5fb6912ca (diff)
downloadgcc-dc51dece7ae902317e9131e153ef53d7bc09c564.zip
gcc-dc51dece7ae902317e9131e153ef53d7bc09c564.tar.gz
gcc-dc51dece7ae902317e9131e153ef53d7bc09c564.tar.bz2
[PR86218] handle ck_aggr in compare_ics in both and either conversion
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
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/call.c9
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr86218.C11
4 files changed, 26 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ff049b5..3cafaaa 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+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
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index c12857d..e9c131d 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -10049,21 +10049,22 @@ compare_ics (conversion *ics1, conversion *ics2)
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)
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 32b3cb1..152dce3 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+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
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr86218.C b/gcc/testsuite/g++.dg/cpp0x/pr86218.C
new file mode 100644
index 0000000..9892ccd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr86218.C
@@ -0,0 +1,11 @@
+// { dg-do compile { target c++11 } }
+
+template <int a>
+void f (const char (&)[a]) { }
+void f (int) { }
+template <class...a>
+void
+g ()
+{
+ f ({2u});
+}