diff options
author | jamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-11-02 15:22:52 +0000 |
---|---|---|
committer | jamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-11-02 15:22:52 +0000 |
commit | b0b0a5abf9a4cf44cb2d7707c40bcdfb304de8de (patch) | |
tree | 6b301cc7b78e84ad831cce83f66b80281b61bc17 /gcc/tree.c | |
parent | 552c6fc05efa4d92e6995985454aae99ce08856d (diff) | |
download | gcc-b0b0a5abf9a4cf44cb2d7707c40bcdfb304de8de.tar.gz |
2010-11-02 Martin Jambor <mjambor@suse.cz>
PR middle-end/46120
* tree.c (get_binfo_at_offset): Bail out on artificial
fields. Identify primary bases according to their offsets.
* testsuite/g++.dg/ipa/ivinline-9.C: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@166192 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree.c')
-rw-r--r-- | gcc/tree.c | 40 |
1 files changed, 21 insertions, 19 deletions
diff --git a/gcc/tree.c b/gcc/tree.c index a7460315658..1cc99f07c67 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -10906,16 +10906,17 @@ lhd_gcc_personality (void) tree get_binfo_at_offset (tree binfo, HOST_WIDE_INT offset, tree expected_type) { - tree type; + tree type = TREE_TYPE (binfo); - type = TREE_TYPE (binfo); - while (offset > 0) + while (true) { - tree base_binfo, found_binfo; HOST_WIDE_INT pos, size; tree fld; int i; + gcc_checking_assert (offset >= 0); + if (type == expected_type) + return binfo; if (TREE_CODE (type) != RECORD_TYPE) return NULL_TREE; @@ -10929,27 +10930,28 @@ get_binfo_at_offset (tree binfo, HOST_WIDE_INT offset, tree expected_type) if (pos <= offset && (pos + size) > offset) break; } - if (!fld) + if (!fld || !DECL_ARTIFICIAL (fld)) return NULL_TREE; - found_binfo = NULL_TREE; - for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) - if (TREE_TYPE (base_binfo) == TREE_TYPE (fld)) - { - found_binfo = base_binfo; - break; - } - - if (!found_binfo) - return NULL_TREE; + /* Offset 0 indicates the primary base, whose vtable contents are + represented in the binfo for the derived class. */ + if (offset != 0) + { + tree base_binfo, found_binfo = NULL_TREE; + for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) + if (TREE_TYPE (base_binfo) == TREE_TYPE (fld)) + { + found_binfo = base_binfo; + break; + } + if (!found_binfo) + return NULL_TREE; + binfo = found_binfo; + } type = TREE_TYPE (fld); - binfo = found_binfo; offset -= pos; } - if (type != expected_type) - return NULL_TREE; - return binfo; } /* Returns true if X is a typedef decl. */ |