[PR86218] handle ck_aggr in compare_ics in both and either conversion
authorAlexandre Oliva <aoliva@redhat.com>
Thu, 7 Feb 2019 07:50:42 +0000 (07:50 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Thu, 7 Feb 2019 07:50:42 +0000 (07:50 +0000)
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

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/pr86218.C [new file with mode: 0644]

index ff049b5de80389e18eefd4852bcbcbfd95c6b3f1..3cafaaad9336afbaca9134032b4b686ec4398d14 100644 (file)
@@ -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
index c12857db1be573a0cbb951f6215df9edab2e4c0b..e9c131dd66b4f6f2da3d58a036bb9e2d34652143 100644 (file)
@@ -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)
        {
index 32b3cb18c380a7cad6f2dc86932763006724a888..152dce3fa8e54c76887a2d329351b47b3b3694b4 100644 (file)
@@ -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 (file)
index 0000000..9892ccd
--- /dev/null
@@ -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});
+}