From: Jan Hubicka Date: Fri, 17 Jan 2014 01:04:59 +0000 (+0100) Subject: re PR ipa/59775 (internal compiler error: Segmentation fault) X-Git-Tag: releases/gcc-4.9.0~1621 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f910753dbe1faad4ec8295f621c5177214fe8232;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e07d1aeefe7d..5a575e01303e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2014-01-16 Jan Hubicka + + PR ipa/59775 + * tree.c (get_binfo_at_offset): Look harder for virtual bases. + 2014-01-16 Bernd Schmidt PR middle-end/56791 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fa17276b77aa..a85acbeac849 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-01-16 Jan Hubicka + + PR ipa/59775 + * g++.dg/torture/pr59775.C: New testcase. + 2014-01-16 Jakub Jelinek 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 000000000000..10c497587e1d --- /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 37a7ed4b3a0b..76e3efb4920d 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);