Hi!

As the comment says, in a valid program we wals find thunk_binfo, but if the
covariancy is invalid, we've already diagnosed error and we might not find
it.  We have case to handle thunk_binfo NULL or not finding it in the chain,
but on the following testcase base_binfo is NULL and we ICE when we try to
access BINFO_TYPE on it.

Fixed thusly, furthermore to match the comment I've added an assertion that
if we don't find thunk_binfo we've indeed already diagnosed an error.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2018-03-27  Jakub Jelinek  <ja...@redhat.com>

        PR c++/85068
        * class.c (update_vtable_entry_for_fn): Don't ICE if base_binfo
        is NULL.  Assert if thunk_binfo is NULL then errorcount is non-zero.

        * g++.dg/inherit/covariant22.C: New test.

--- gcc/cp/class.c.jj   2018-03-21 21:18:31.691351383 +0100
+++ gcc/cp/class.c      2018-03-26 10:48:02.648053297 +0200
@@ -2479,19 +2479,20 @@ update_vtable_entry_for_fn (tree t, tree
             order.  Of course it is lame that we have to repeat the
             search here anyway -- we should really be caching pieces
             of the vtable and avoiding this repeated work.  */
-         tree thunk_binfo, base_binfo;
+         tree thunk_binfo = NULL_TREE;
+         tree base_binfo = TYPE_BINFO (base_return);
 
          /* Find the base binfo within the overriding function's
             return type.  We will always find a thunk_binfo, except
             when the covariancy is invalid (which we will have
             already diagnosed).  */
-         for (base_binfo = TYPE_BINFO (base_return),
-              thunk_binfo = TYPE_BINFO (over_return);
-              thunk_binfo;
-              thunk_binfo = TREE_CHAIN (thunk_binfo))
-           if (SAME_BINFO_TYPE_P (BINFO_TYPE (thunk_binfo),
-                                  BINFO_TYPE (base_binfo)))
-             break;
+         if (base_binfo)
+           for (thunk_binfo = TYPE_BINFO (over_return); thunk_binfo;
+                thunk_binfo = TREE_CHAIN (thunk_binfo))
+             if (SAME_BINFO_TYPE_P (BINFO_TYPE (thunk_binfo),
+                                    BINFO_TYPE (base_binfo)))
+               break;
+         gcc_assert (thunk_binfo || errorcount);
 
          /* See if virtual inheritance is involved.  */
          for (virtual_offset = thunk_binfo;
--- gcc/testsuite/g++.dg/inherit/covariant22.C.jj       2018-03-26 
10:51:59.580172775 +0200
+++ gcc/testsuite/g++.dg/inherit/covariant22.C  2018-03-26 10:49:21.038092826 
+0200
@@ -0,0 +1,19 @@
+// PR c++/85068
+// { dg-do compile }
+
+struct A;
+
+struct B
+{
+  virtual A *foo ();   // { dg-error "overriding" }
+};
+
+struct C : virtual B
+{
+  virtual C *foo ();   // { dg-error "invalid covariant return type for" }
+};
+
+struct D : C
+{
+  virtual C *foo ();
+};

        Jakub

Reply via email to