aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2010-11-02 16:22:52 +0100
committerMartin Jambor <jamborm@gcc.gnu.org>2010-11-02 16:22:52 +0100
commit4c2030661e0a9bce68786f72e4d0da1be5caf3a5 (patch)
tree6b301cc7b78e84ad831cce83f66b80281b61bc17 /gcc/tree.c
parent7a2b3e20767d3d11776e4c5bbb12d751e7ba748f (diff)
downloadgcc-4c2030661e0a9bce68786f72e4d0da1be5caf3a5.zip
gcc-4c2030661e0a9bce68786f72e4d0da1be5caf3a5.tar.gz
gcc-4c2030661e0a9bce68786f72e4d0da1be5caf3a5.tar.bz2
re PR middle-end/46120 (g++.dg/ipa/ivinline-?.C)
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. From-SVN: r166192
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 a746031..1cc99f0 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. */