aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2014-01-17 02:04:59 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2014-01-17 01:04:59 +0000
commitf910753dbe1faad4ec8295f621c5177214fe8232 (patch)
treea2d3c118085cdca5895c149b8c25b020c147fc99
parent906641605ffa86e1ab4173779dd72ea5e04ae78b (diff)
downloadgcc-f910753dbe1faad4ec8295f621c5177214fe8232.zip
gcc-f910753dbe1faad4ec8295f621c5177214fe8232.tar.gz
gcc-f910753dbe1faad4ec8295f621c5177214fe8232.tar.bz2
re PR ipa/59775 (internal compiler error: Segmentation fault)
PR ipa/59775 * tree.c (get_binfo_at_offset): Look harder for virtual bases. From-SVN: r206694
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/torture/pr59775.C21
-rw-r--r--gcc/tree.c39
4 files changed, 60 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e07d1ae..5a575e0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2014-01-16 Jan Hubicka <jh@suse.cz>
+
+ PR ipa/59775
+ * tree.c (get_binfo_at_offset): Look harder for virtual bases.
+
2014-01-16 Bernd Schmidt <bernds@codesourcery.com>
PR middle-end/56791
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index fa17276..a85acbe 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2014-01-16 Jan Hubicka <jh@suse.cz>
+
+ PR ipa/59775
+ * g++.dg/torture/pr59775.C: New testcase.
+
2014-01-16 Jakub Jelinek <jakub@redhat.com>
PR middle-end/58344
diff --git a/gcc/testsuite/g++.dg/torture/pr59775.C b/gcc/testsuite/g++.dg/torture/pr59775.C
new file mode 100644
index 0000000..10c4975
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr59775.C
@@ -0,0 +1,21 @@
+// { dg-do compile }
+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 ();
+}
diff --git a/gcc/tree.c b/gcc/tree.c
index 37a7ed4..76e3efb 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -11995,16 +11995,35 @@ get_binfo_at_offset (tree binfo, HOST_WIDE_INT offset, tree expected_type)
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);