Patchwork [PR,45875] Devirtualization with virtual inheritace

login
register
mail settings
Submitter Martin Jambor
Date Nov. 2, 2010, 3:12 p.m.
Message ID <20101102151219.GB3200@virgil.arch.suse.de>
Download mbox | patch
Permalink /patch/69895/
State New
Headers show

Comments

Martin Jambor - Nov. 2, 2010, 3:12 p.m.
On Mon, Nov 01, 2010 at 03:23:26PM -0400, Jason Merrill wrote:
> On 11/01/2010 11:49 AM, Martin Jambor wrote:
> >+	  if (int_bit_position (field) != 0)
> 
> Any particular reason for choosing bit position rather than byte?

Not in this function but in get_binfo_at_offset I need it because it
is fed the output of get_ref_base_and_extent which returns bits.  So I
just used the same thing.

> 
> OK either way.

Thanks, I have re-formulated the comment about primary classes and
committed the following as revision 166190.

Thanks,

Martin


2010-11-02  Martin Jambor  <mjambor@suse.cz>

	PR tree-optimization/45875
	* gimple-fold.c (get_first_base_binfo_with_virtuals): Removed.
	(gimple_get_relevant_ref_binfo): Detect primary bases according to
	their field offset.

	* testsuite/g++.dg/torture/pr45875.C: New test.

Patch

Index: icln/gcc/gimple-fold.c
===================================================================
--- icln.orig/gcc/gimple-fold.c
+++ icln/gcc/gimple-fold.c
@@ -1360,22 +1360,6 @@  gimple_fold_builtin (gimple stmt)
   return result;
 }
 
-/* Return the first of the base binfos of BINFO that has virtual functions.  */
-
-static tree
-get_first_base_binfo_with_virtuals (tree binfo)
-{
-  int i;
-  tree base_binfo;
-
-  for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
-    if (BINFO_VIRTUALS (base_binfo))
-      return base_binfo;
-
-  return NULL_TREE;
-}
-
-
 /* Search for a base binfo of BINFO that corresponds to TYPE and return it if
    it is found or NULL_TREE if it is not.  */
 
@@ -1413,7 +1397,7 @@  gimple_get_relevant_ref_binfo (tree ref,
       if (TREE_CODE (ref) == COMPONENT_REF)
 	{
 	  tree par_type;
-	  tree binfo, base_binfo;
+	  tree binfo;
 	  tree field = TREE_OPERAND (ref, 1);
 
 	  if (!DECL_ARTIFICIAL (field))
@@ -1431,14 +1415,15 @@  gimple_get_relevant_ref_binfo (tree ref,
 	      || BINFO_N_BASE_BINFOS (binfo) == 0)
 	    return NULL_TREE;
 
-	  base_binfo = get_first_base_binfo_with_virtuals (binfo);
-	  if (base_binfo && BINFO_TYPE (base_binfo) != TREE_TYPE (field))
+	  /* Offset 0 indicates the primary base, whose vtable contents are
+	     represented in the binfo for the derived class.  */
+	  if (int_bit_position (field) != 0)
 	    {
 	      tree d_binfo;
 
+	      /* Get descendant binfo. */
 	      d_binfo = gimple_get_relevant_ref_binfo (TREE_OPERAND (ref, 0),
 						       known_binfo);
-	      /* Get descendant binfo. */
 	      if (!d_binfo)
 		return NULL_TREE;
 	      return get_base_binfo_for_type (d_binfo, TREE_TYPE (field));
Index: icln/gcc/testsuite/g++.dg/torture/pr45875.C
===================================================================
--- /dev/null
+++ icln/gcc/testsuite/g++.dg/torture/pr45875.C
@@ -0,0 +1,25 @@ 
+// { dg-do compile }
+
+struct c1 {};
+
+struct c10 : c1
+{
+  virtual void foo ();
+};
+
+struct c11 : c10, c1		//  // { dg-warning "" }
+{
+  virtual void f6 ();
+};
+
+struct c28 : virtual c11
+{
+  void f6 ();
+};
+
+void check_c28 ()
+{
+  c28 obj;
+  c11 *ptr = &obj;
+  ptr->f6 ();
+}