summaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
authorjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>2010-11-02 15:22:52 +0000
committerjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>2010-11-02 15:22:52 +0000
commitb0b0a5abf9a4cf44cb2d7707c40bcdfb304de8de (patch)
tree6b301cc7b78e84ad831cce83f66b80281b61bc17 /gcc/tree.c
parent552c6fc05efa4d92e6995985454aae99ce08856d (diff)
downloadgcc-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.c40
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. */