This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PR ipa/59882


Hi,
this patch fixes two bugs I introducedinto get_binfo_at_offset in the previous changes.
First BINFO_OFFSET is pointer to INTEGER_CST and not integer as the code assumes.
Second the code gets confused by presence of empty classes (such as in testcase) that
may interpose with non-empty.
I fixed it by looking only into basses with virtual table.

Bootstrapped/regtested x86_64-linux, comitted.

Honza

	PR ipa/59882
	* tree.c (get_binfo_at_offset): Do not get confused by empty classes;
	* g++.dg/torture/pr59882.C: New testcase
Index: tree.c
===================================================================
--- tree.c	(revision 207438)
+++ tree.c	(working copy)
@@ -12005,10 +12005,15 @@ get_binfo_at_offset (tree binfo, HOST_WI
 		    break;
 		  }
 		else
-		  if (BINFO_OFFSET (base_binfo) - BINFO_OFFSET (binfo) < pos
+		  if ((tree_to_shwi (BINFO_OFFSET (base_binfo)) 
+		       - tree_to_shwi (BINFO_OFFSET (binfo)))
+		      * BITS_PER_UNIT < pos
+		      /* Rule out types with no virtual methods or we can get confused
+			 here by zero sized bases.  */
+		      && BINFO_VTABLE (TYPE_BINFO (BINFO_TYPE (base_binfo)))
 		      && (!containing_binfo
-			  || (BINFO_OFFSET (containing_binfo)
-			      < BINFO_OFFSET (base_binfo))))
+			  || (tree_to_shwi (BINFO_OFFSET (containing_binfo))
+			      < tree_to_shwi (BINFO_OFFSET (base_binfo)))))
 		    containing_binfo = base_binfo;
 	      if (found_binfo)
 		{
Index: testsuite/g++.dg/torture/pr59882.C
===================================================================
--- testsuite/g++.dg/torture/pr59882.C	(revision 0)
+++ testsuite/g++.dg/torture/pr59882.C	(revision 0)
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+class A;
+class B {};
+struct C {
+  virtual void dispatch();
+  int traversal_map_;
+};
+template <typename> class F : public virtual C {};
+
+struct I : F<A>, F<int> {};
+struct J : B, I {};
+class D {};
+struct L {
+  L(D &, int &p2) : map_(p2) {}
+  virtual void traverse(int &p1) {
+    int &s = p1;
+    names<L>(s, names_);
+  }
+  int &map_;
+  J names_;
+  template <typename> void names(int &, C &p2) { p2.dispatch(); }
+};
+
+struct G : D {
+  G(D &, int &p2) : map_(p2) { L(*this, map_); }
+  int &map_;
+};
+
+int a;
+void fn1(D &p1) { G(p1, a); }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]