diff options
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r-- | gcc/cp/class.c | 66 |
1 files changed, 45 insertions, 21 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c index b57200fae3e..0e3e6570359 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -1,6 +1,7 @@ /* Functions related to building classes and their related objects. Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005 + Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GCC. @@ -2115,6 +2116,9 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals, also be converting to the return type of FN, we have to combine the two conversions here. */ tree fixed_offset, virtual_offset; + + over_return = TREE_TYPE (over_return); + base_return = TREE_TYPE (base_return); if (DECL_THUNK_P (fn)) { @@ -2132,32 +2136,51 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals, virtual_offset = TREE_VALUE (purpose_member (BINFO_TYPE (virtual_offset), - CLASSTYPE_VBASECLASSES (TREE_TYPE (over_return)))); - else if (!same_type_p (TREE_TYPE (over_return), - TREE_TYPE (base_return))) + CLASSTYPE_VBASECLASSES (over_return))); + else if (!same_type_ignoring_top_level_qualifiers_p + (over_return, base_return)) { - /* There was no existing virtual thunk (which takes - precedence). */ - tree thunk_binfo; - base_kind kind; + /* There was no existing virtual thunk (which takes + precedence). So find the binfo of the base function's + return type within the overriding function's return type. + We cannot call lookup base here, because we're inside a + dfs_walk, and will therefore clobber the BINFO_MARKED + flags. Fortunately we know the covariancy is valid (it + has already been checked), so we can just iterate along + the binfos, which have been chained in inheritance graph + order. Of course it is lame that we have to repeat the + search here anyway -- we should really be caching pieces + of the vtable and avoiding this repeated work. */ + tree thunk_binfo, base_binfo; + + /* Find the base binfo within the overriding function's + return type. We will always find a thunk_binfo, except + when the covariancy is invalid (which we will have + already diagnosed). */ + for (base_binfo = TYPE_BINFO (base_return), + thunk_binfo = TYPE_BINFO (over_return); + thunk_binfo; + thunk_binfo = TREE_CHAIN (thunk_binfo)) + if (same_type_p (BINFO_TYPE (thunk_binfo), + BINFO_TYPE (base_binfo))) + break; - thunk_binfo = lookup_base (TREE_TYPE (over_return), - TREE_TYPE (base_return), - ba_check | ba_quiet, &kind); - - if (thunk_binfo && (kind == bk_via_virtual - || !BINFO_OFFSET_ZEROP (thunk_binfo))) + /* See if virtual inheritance is involved. */ + for (virtual_offset = thunk_binfo; + virtual_offset; + virtual_offset = BINFO_INHERITANCE_CHAIN (virtual_offset)) + if (TREE_VIA_VIRTUAL (virtual_offset)) + break; + + if (virtual_offset + || (thunk_binfo && !BINFO_OFFSET_ZEROP (thunk_binfo))) { tree offset = convert (ssizetype, BINFO_OFFSET (thunk_binfo)); - if (kind == bk_via_virtual) + if (virtual_offset) { - /* We convert via virtual base. Find the virtual - base and adjust the fixed offset to be from there. */ - while (!TREE_VIA_VIRTUAL (thunk_binfo)) - thunk_binfo = BINFO_INHERITANCE_CHAIN (thunk_binfo); - - virtual_offset = thunk_binfo; + /* We convert via virtual base. Adjust the fixed + offset to be from there. */ offset = size_diffop (offset, convert (ssizetype, BINFO_OFFSET (virtual_offset))); @@ -5232,6 +5255,7 @@ finish_struct (tree t, tree attributes) { finish_struct_methods (t); TYPE_SIZE (t) = bitsize_zero_node; + TYPE_SIZE_UNIT (t) = size_zero_node; } else finish_struct_1 (t); |