public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* PR ipa/59775 (get_binfo_at_offset not handling virtual inheritance well)
@ 2014-01-15 21:22 Jan Hubicka
  2014-01-15 21:27 ` Jan Hubicka
  2014-01-16  8:44 ` Richard Biener
  0 siblings, 2 replies; 4+ messages in thread
From: Jan Hubicka @ 2014-01-15 21:22 UTC (permalink / raw)
  To: jason, jakub, rguenther, mjambor, gcc-patches

Hi,
this patch fixes ICE in ipa-devirt that is caused by get_binfo_at_offset
reporting NULL for a valid query.  This is because how virtual inheritance
is represented.

Here we have chain A<-B<-C where A is a virtual base.  We look for A within
C that is there at offset 64.  On this query get_binfo_at_offset walks
fields of C and it finds A, it matches it and it looks for BINFO. The
catch is that BINFO represents only direct bases and A is not direct base.
Conseuqentely it returns NULL. In the past this only prevented us from
devirtualizing here, now we ICE, since ipa-devirt depends on fact that
it can resolve all possible queries. get_binfo_at_offset needs to make a hop
through B.

This patch is kind of minimal change needed to get get_binfo_at_offset to
look into B: when base is not found, it finds a base that contains A
and dives into it.

I plan to rewrite the function for next stage1: the walk of fields is already
done by ipa-devirt separately, so it really should do only BINFO walk.  For
that we however need to retire other uses of get_binfo_at_offset that are still
used by ipa-devirt.  That is on the TODO list to switch it to be basically a
propagation engine for ipa-devirt's polymorphic_call_context structures.
(basically I want to have one local pass doing non-trivial propagation and
one IPA pass propagation across function boundaries, both sharing
polymorphic_call_context structure and a lattice operations)

Bootstrapped/regtested x86_64-linux, OK with the testcase?

struct A
{
  virtual void foo () = 0;
  void bar () { foo (); }
  bool a;
};
struct B : public virtual A
{
  virtual void foo ();
};
struct C : public B
{
  C ();
};
void
baz ()
{
  C c;
  c.bar ();
}
	PR ipa/59775
	* tree.c (get_binfo_at_offset): Look harder for virtual bases.
Index: tree.c
===================================================================
--- tree.c	(revision 206617)
+++ tree.c	(working copy)
@@ -11995,16 +11995,35 @@ get_binfo_at_offset (tree binfo, HOST_WI
 	 represented in the binfo for the derived class.  */
       else if (offset != 0)
 	{
-	  tree base_binfo, found_binfo = NULL_TREE;
-	  for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
-	    if (types_same_for_odr (TREE_TYPE (base_binfo), TREE_TYPE (fld)))
-	      {
-		found_binfo = base_binfo;
-		break;
-	      }
-	  if (!found_binfo)
-	    return NULL_TREE;
-	  binfo = found_binfo;
+	  tree base_binfo, binfo2 = binfo;
+
+	  /* Find BINFO corresponding to FLD.  This is bit harder
+	     by a fact that in virtual inheritance we may need to walk down
+	     the non-virtual inheritance chain.  */
+	  while (true)
+	    {
+	      tree containing_binfo = NULL, found_binfo = NULL;
+	      for (i = 0; BINFO_BASE_ITERATE (binfo2, i, base_binfo); i++)
+		if (types_same_for_odr (TREE_TYPE (base_binfo), TREE_TYPE (fld)))
+		  {
+		    found_binfo = base_binfo;
+		    break;
+		  }
+		else
+		  if (BINFO_OFFSET (base_binfo) - BINFO_OFFSET (binfo) < pos
+		      && (!containing_binfo
+			  || (BINFO_OFFSET (containing_binfo)
+			      < BINFO_OFFSET (base_binfo))))
+		    containing_binfo = base_binfo;
+	      if (found_binfo)
+		{
+		  binfo = found_binfo;
+		  break;
+		}
+	      if (!containing_binfo)
+		return NULL_TREE;
+	      binfo2 = containing_binfo;
+	    }
 	}
 
       type = TREE_TYPE (fld);

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-01-16 18:45 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-01-15 21:22 PR ipa/59775 (get_binfo_at_offset not handling virtual inheritance well) Jan Hubicka
2014-01-15 21:27 ` Jan Hubicka
2014-01-16  8:44 ` Richard Biener
2014-01-16 18:45   ` Jan Hubicka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).