This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PR ipa/59882
- From: Jan Hubicka <hubicka at ucw dot cz>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 4 Feb 2014 07:31:25 +0100
- Subject: PR ipa/59882
- Authentication-results: sourceware.org; auth=none
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); }