[C++] Fix invalid covariant return error-recovery (PR c++/85068)

Message ID 20180327084923.GT8577@tucnak
State New
Headers show
Series
  • [C++] Fix invalid covariant return error-recovery (PR c++/85068)
Related show

Commit Message

Jakub Jelinek March 27, 2018, 8:49 a.m.
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  <jakub@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.


	Jakub

Comments

Nathan Sidwell March 27, 2018, 10:50 a.m. | #1
On 03/27/2018 04:49 AM, Jakub Jelinek wrote:
> 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  <jakub@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.

> 


ok, thanks.

nathan

-- 
Nathan Sidwell

Patch

--- 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 ();
+};