From: Nathan Sidwell Date: Tue, 12 Jun 2001 18:08:05 +0000 (+0000) Subject: PR c++/3130, c++/3131, c++/3132 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=623fe76a4c9035ec908db4c6f61e9f191dd657aa;p=gcc.git PR c++/3130, c++/3131, c++/3132 cp: PR c++/3130, c++/3131, c++/3132 * cp-tree.h (BINFO_UNSHARED_MARKED): New #define. * class.c (force_canonical_binfo_r): Move BINFO_UNSHARED_MARKED, BINFO_LOST_PRIMARY_P. Don't move virtual bases unless they're primary and what they're primary too has been moved. (dfs_unshared_virtual_bases): Use BINFO_UNSHARED_MARKED. Cope with morally virtual bases. Duplicate BINFO_LOST_PRIMARY_P and BINFO_PRIMARY_BASE_OF. Clear BINFO_VTABLE for all but the most derived binfo. (mark_primary_bases): Use BINFO_UNSHARED_MARKED. (layout_nonempty_base_or_field): Add most derived type parameter. Adjust. (layout_empty_base): Likewise. (build_base_field): Likewise. (build_base_fields): Likewise. (propagate_binfo_offsets): Add most derived type parameter. Skip non canonical virtual bases too. (dfs_set_offset_for_unshared_vbases): Don't skip primary bases. Do skip canonical bases. (layout_virtual_bases): Adjust. (layout_class_type): Adjust. (dfs_get_primary_binfo): Build list of virtual primary base candidates. (get_primary_binfo): Check that the shared virtual primary base candidate was found first. (accumulate_vtbl_inits): Don't do anything for non-vptr containing binfos. For case 1 primary virtual bases, keep checking that we've not emerged from the hierarchy of RTTI_BINFO. testsuite: * g++.old-deja/g++.abi/vbase5.C: New test. * g++.old-deja/g++.abi/vbase6.C: New test. * g++.old-deja/g++.abi/vbase7.C: New test. From-SVN: r43266 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 577038eccc2..5df346cebad 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,35 @@ +2001-06-12 Nathan Sidwell + + PR c++/3130, c++/3131, c++/3132 + * cp-tree.h (BINFO_UNSHARED_MARKED): New #define. + * class.c (force_canonical_binfo_r): Move + BINFO_UNSHARED_MARKED, BINFO_LOST_PRIMARY_P. Don't move + virtual bases unless they're primary and what they're primary + too has been moved. + (dfs_unshared_virtual_bases): Use BINFO_UNSHARED_MARKED. Cope + with morally virtual bases. Duplicate BINFO_LOST_PRIMARY_P and + BINFO_PRIMARY_BASE_OF. Clear BINFO_VTABLE for all but the most + derived binfo. + (mark_primary_bases): Use BINFO_UNSHARED_MARKED. + (layout_nonempty_base_or_field): Add most derived type + parameter. Adjust. + (layout_empty_base): Likewise. + (build_base_field): Likewise. + (build_base_fields): Likewise. + (propagate_binfo_offsets): Add most derived type + parameter. Skip non canonical virtual bases too. + (dfs_set_offset_for_unshared_vbases): Don't skip primary + bases. Do skip canonical bases. + (layout_virtual_bases): Adjust. + (layout_class_type): Adjust. + (dfs_get_primary_binfo): Build list of virtual primary base + candidates. + (get_primary_binfo): Check that the shared virtual primary + base candidate was found first. + (accumulate_vtbl_inits): Don't do anything for non-vptr + containing binfos. For case 1 primary virtual bases, keep + checking that we've not emerged from the hierarchy of RTTI_BINFO. + 2001-06-12 Nathan Sidwell PR c++/3089 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index a0cd2ce1c9e..c1347b3cb33 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -144,9 +144,9 @@ static void check_field_decl PARAMS ((tree, tree, int *, int *, int *, int *)); static void check_field_decls PARAMS ((tree, tree *, int *, int *, int *, int *)); static bool build_base_field PARAMS ((record_layout_info, tree, int *, - splay_tree)); + splay_tree, tree)); static bool build_base_fields PARAMS ((record_layout_info, int *, - splay_tree)); + splay_tree, tree)); static tree build_vbase_pointer_fields PARAMS ((record_layout_info, int *)); static tree build_vtbl_or_vbase_field PARAMS ((tree, tree, tree, tree, tree, int *)); @@ -159,7 +159,7 @@ static void layout_class_type PARAMS ((tree, int *, int *, tree *, tree *)); static void fixup_pending_inline PARAMS ((tree)); static void fixup_inline_methods PARAMS ((tree)); static void set_primary_base PARAMS ((tree, tree, int *)); -static void propagate_binfo_offsets PARAMS ((tree, tree)); +static void propagate_binfo_offsets PARAMS ((tree, tree, tree)); static void layout_virtual_bases PARAMS ((tree, splay_tree)); static tree dfs_set_offset_for_unshared_vbases PARAMS ((tree, void *)); static void build_vbase_offset_vtbl_entries PARAMS ((tree, vtbl_init_data *)); @@ -181,9 +181,9 @@ static void initialize_vtable PARAMS ((tree, tree)); static void initialize_array PARAMS ((tree, tree)); static void layout_nonempty_base_or_field PARAMS ((record_layout_info, tree, tree, - splay_tree)); + splay_tree, tree)); static unsigned HOST_WIDE_INT end_of_class PARAMS ((tree, int)); -static bool layout_empty_base PARAMS ((tree, tree, splay_tree)); +static bool layout_empty_base PARAMS ((tree, tree, splay_tree, tree)); static void accumulate_vtbl_inits PARAMS ((tree, tree, tree, tree, tree)); static tree dfs_accumulate_vtbl_inits PARAMS ((tree, tree, tree, tree, tree)); @@ -1676,6 +1676,10 @@ force_canonical_binfo_r (to, from, type, mappings) BINFO_INDIRECT_PRIMARY_P (to) = BINFO_INDIRECT_PRIMARY_P (from); BINFO_INDIRECT_PRIMARY_P (from) = 0; + BINFO_UNSHARED_MARKED (to) = BINFO_UNSHARED_MARKED (from); + BINFO_UNSHARED_MARKED (from) = 0; + BINFO_LOST_PRIMARY_P (to) = BINFO_LOST_PRIMARY_P (from); + BINFO_LOST_PRIMARY_P (from) = 0; if (BINFO_PRIMARY_P (from)) { tree primary = BINFO_PRIMARY_BASE_OF (from); @@ -1689,7 +1693,8 @@ force_canonical_binfo_r (to, from, type, mappings) BINFO_PRIMARY_BASE_OF (to) = primary; BINFO_PRIMARY_BASE_OF (from) = NULL_TREE; } - my_friendly_assert (same_type_p (BINFO_TYPE (to), BINFO_TYPE (from)), 20010104); + my_friendly_assert (same_type_p (BINFO_TYPE (to), BINFO_TYPE (from)), + 20010104); mappings = tree_cons (from, to, mappings); for (i = 0; i != n_baseclasses; i++) { @@ -1698,9 +1703,10 @@ force_canonical_binfo_r (to, from, type, mappings) if (TREE_VIA_VIRTUAL (from_binfo)) { - tree shared_binfo = binfo_for_vbase (BINFO_TYPE (from_binfo), type); - - if (shared_binfo == from_binfo) + if (BINFO_PRIMARY_P (from_binfo) && + purpose_member (BINFO_PRIMARY_BASE_OF (from_binfo), mappings)) + /* This base is a primary of some binfo we have already + reseated. We must reseat this one too. */ force_canonical_binfo (to_binfo, from_binfo, type, mappings); } else @@ -1764,7 +1770,7 @@ mark_primary_virtual_base (binfo, base_binfo, type) delta = size_diffop (BINFO_OFFSET (binfo), BINFO_OFFSET (base_binfo)); if (!integer_zerop (delta)) { - propagate_binfo_offsets (base_binfo, delta); + propagate_binfo_offsets (base_binfo, delta, type); BINFO_OFFSET (base_binfo) = BINFO_OFFSET (binfo); } return base_binfo; @@ -1772,19 +1778,43 @@ mark_primary_virtual_base (binfo, base_binfo, type) /* If BINFO is an unmarked virtual binfo for a class with a primary virtual base, then BINFO has no primary base in this graph. Called from - mark_primary_bases. */ + mark_primary_bases. DATA is the most derived type. */ static tree dfs_unshared_virtual_bases (binfo, data) tree binfo; - void *data ATTRIBUTE_UNUSED; + void *data; { - if (TREE_VIA_VIRTUAL (binfo) && !BINFO_MARKED (binfo) - && CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (binfo)) - && TREE_VIA_VIRTUAL (CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (binfo)))) - BINFO_LOST_PRIMARY_P (binfo) = 1; - - CLEAR_BINFO_MARKED (binfo); + tree t = (tree) data; + + if (!BINFO_UNSHARED_MARKED (binfo) + && CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (binfo))) + { + /* This morally virtual base has a primary base when it + is a complete object. We need to locate the shared instance + of this binfo in the type dominated by T. We duplicate the + primary base information from there to here. */ + tree vbase; + tree unshared_base; + + for (vbase = binfo; !TREE_VIA_VIRTUAL (vbase); + vbase = BINFO_INHERITANCE_CHAIN (vbase)) + continue; + unshared_base = get_original_base (binfo, + binfo_for_vbase (BINFO_TYPE (vbase), + t)); + my_friendly_assert (unshared_base != binfo, 20010612); + BINFO_LOST_PRIMARY_P (binfo) = BINFO_LOST_PRIMARY_P (unshared_base); + if (!BINFO_LOST_PRIMARY_P (binfo)) + BINFO_PRIMARY_BASE_OF (get_primary_binfo (binfo)) = binfo; + } + + if (binfo != TYPE_BINFO (t)) + /* The vtable fields will have been copied when duplicating the + base binfos. That information is bogus, make sure we don't try + and use it. */ + BINFO_VTABLE (binfo) = NULL_TREE; + BINFO_UNSHARED_MARKED (binfo) = 0; return NULL; } @@ -1813,12 +1843,13 @@ mark_primary_bases (type) if (base_binfo) BINFO_PRIMARY_BASE_OF (base_binfo) = binfo; - SET_BINFO_MARKED (binfo); + + BINFO_UNSHARED_MARKED (binfo) = 1; } - /* There could remain unshared virtual bases which were not visited + /* There could remain unshared morally virtual bases which were not visited in the inheritance graph walk. These bases will have lost their - primary base (should they have one). We must now find them. */ - dfs_walk (TYPE_BINFO (type), dfs_unshared_virtual_bases, NULL, NULL); + virtual primary base (should they have one). We must now find them. */ + dfs_walk (TYPE_BINFO (type), dfs_unshared_virtual_bases, NULL, type); } /* Make the BINFO the primary base of T. */ @@ -3933,15 +3964,16 @@ layout_conflict_p (type, offset, offsets, vbases_p) /* DECL is a FIELD_DECL corresponding either to a base subobject of a non-static data member of the type indicated by RLI. BINFO is the binfo corresponding to the base subobject, OFFSETS maps offsets to - types already located at those offsets. This function determines - the position of the DECL. */ + types already located at those offsets. T is the most derived + type. This function determines the position of the DECL. */ static void -layout_nonempty_base_or_field (rli, decl, binfo, offsets) +layout_nonempty_base_or_field (rli, decl, binfo, offsets, t) record_layout_info rli; tree decl; tree binfo; splay_tree offsets; + tree t; { tree offset = NULL_TREE; tree type = TREE_TYPE (decl); @@ -3998,24 +4030,25 @@ layout_nonempty_base_or_field (rli, decl, binfo, offsets) break; } - /* Now that we know where it wil be placed, update its + /* Now that we know where it will be placed, update its BINFO_OFFSET. */ if (binfo && CLASS_TYPE_P (BINFO_TYPE (binfo))) propagate_binfo_offsets (binfo, - convert (ssizetype, offset)); + convert (ssizetype, offset), t); } /* Layout the empty base BINFO. EOC indicates the byte currently just past the end of the class, and should be correctly aligned for a class of the type indicated by BINFO; OFFSETS gives the offsets of - the empty bases allocated so far. Return non-zero iff we added it - at the end. */ + the empty bases allocated so far. T is the most derived + type. Return non-zero iff we added it at the end. */ static bool -layout_empty_base (binfo, eoc, offsets) +layout_empty_base (binfo, eoc, offsets, t) tree binfo; tree eoc; splay_tree offsets; + tree t; { tree alignment; tree basetype = BINFO_TYPE (binfo); @@ -4035,7 +4068,7 @@ layout_empty_base (binfo, eoc, offsets) /* That didn't work. Now, we move forward from the next available spot in the class. */ atend = true; - propagate_binfo_offsets (binfo, convert (ssizetype, eoc)); + propagate_binfo_offsets (binfo, convert (ssizetype, eoc), t); while (1) { if (!layout_conflict_p (BINFO_TYPE (binfo), @@ -4046,7 +4079,7 @@ layout_empty_base (binfo, eoc, offsets) break; /* There's overlap here, too. Bump along to the next spot. */ - propagate_binfo_offsets (binfo, alignment); + propagate_binfo_offsets (binfo, alignment, t); } } return atend; @@ -4055,15 +4088,17 @@ layout_empty_base (binfo, eoc, offsets) /* Build a FIELD_DECL for the base given by BINFO in the class indicated by RLI. If the new object is non-empty, clear *EMPTY_P. *BASE_ALIGN is a running maximum of the alignments of any base - class. OFFSETS gives the location of empty base subobjects. Return - non-zero if the new object cannot be nearly-empty. */ + class. OFFSETS gives the location of empty base subobjects. T is + the most derived type. Return non-zero if the new object cannot be + nearly-empty. */ static bool -build_base_field (rli, binfo, empty_p, offsets) +build_base_field (rli, binfo, empty_p, offsets, t) record_layout_info rli; tree binfo; int *empty_p; splay_tree offsets; + tree t; { tree basetype = BINFO_TYPE (binfo); tree decl; @@ -4091,7 +4126,7 @@ build_base_field (rli, binfo, empty_p, offsets) /* Try to place the field. It may take more than one try if we have a hard time placing the field without putting two objects of the same type at the same address. */ - layout_nonempty_base_or_field (rli, decl, binfo, offsets); + layout_nonempty_base_or_field (rli, decl, binfo, offsets, t); } else { @@ -4101,7 +4136,7 @@ build_base_field (rli, binfo, empty_p, offsets) byte-aligned. */ eoc = tree_low_cst (rli_size_unit_so_far (rli), 0); eoc = CEIL (eoc, DECL_ALIGN_UNIT (decl)) * DECL_ALIGN_UNIT (decl); - atend |= layout_empty_base (binfo, size_int (eoc), offsets); + atend |= layout_empty_base (binfo, size_int (eoc), offsets, t); } /* Record the offsets of BINFO and its base subobjects. */ @@ -4113,14 +4148,15 @@ build_base_field (rli, binfo, empty_p, offsets) } /* Layout all of the non-virtual base classes. Record empty - subobjects in OFFSETS. Return non-zero if the type cannot be nearly - empty. */ + subobjects in OFFSETS. T is the most derived type. Return + non-zero if the type cannot be nearly empty. */ static bool -build_base_fields (rli, empty_p, offsets) +build_base_fields (rli, empty_p, offsets, t) record_layout_info rli; int *empty_p; splay_tree offsets; + tree t; { /* Chain to hold all the new FIELD_DECLs which stand in for base class subobjects. */ @@ -4133,7 +4169,7 @@ build_base_fields (rli, empty_p, offsets) first. */ if (CLASSTYPE_HAS_PRIMARY_BASE_P (rec)) build_base_field (rli, CLASSTYPE_PRIMARY_BINFO (rec), - empty_p, offsets); + empty_p, offsets, t); /* Now allocate the rest of the bases. */ for (i = 0; i < n_baseclasses; ++i) @@ -4154,7 +4190,7 @@ build_base_fields (rli, empty_p, offsets) && !BINFO_PRIMARY_P (base_binfo)) continue; - atend |= build_base_field (rli, base_binfo, empty_p, offsets); + atend |= build_base_field (rli, base_binfo, empty_p, offsets, t); } return atend; } @@ -4728,9 +4764,10 @@ fixup_inline_methods (type) OFFSET, which is a type offset, is number of bytes. */ static void -propagate_binfo_offsets (binfo, offset) +propagate_binfo_offsets (binfo, offset, t) tree binfo; tree offset; + tree t; { int i; tree primary_binfo; @@ -4751,9 +4788,9 @@ propagate_binfo_offsets (binfo, offset) { tree base_binfo; - /* On the first through the loop, do the primary base. Because - the primary base need not be an immediate base, we must - handle the primary base specially. */ + /* On the first time through the loop, do the primary base. + Because the primary base need not be an immediate base, we + must handle the primary base specially. */ if (i == -1) { if (!primary_binfo) @@ -4769,12 +4806,13 @@ propagate_binfo_offsets (binfo, offset) continue; } - /* Skip virtual bases that aren't our primary base. */ + /* Skip virtual bases that aren't our canonical primary base. */ if (TREE_VIA_VIRTUAL (base_binfo) - && BINFO_PRIMARY_BASE_OF (base_binfo) != binfo) + && (BINFO_PRIMARY_BASE_OF (base_binfo) != binfo + || base_binfo != binfo_for_vbase (BINFO_TYPE (base_binfo), t))) continue; - propagate_binfo_offsets (base_binfo, offset); + propagate_binfo_offsets (base_binfo, offset, t); } } @@ -4788,15 +4826,18 @@ dfs_set_offset_for_unshared_vbases (binfo, data) /* If this is a virtual base, make sure it has the same offset as the shared copy. If it's a primary base, then we know it's correct. */ - if (TREE_VIA_VIRTUAL (binfo) && !BINFO_PRIMARY_P (binfo)) + if (TREE_VIA_VIRTUAL (binfo)) { tree t = (tree) data; tree vbase; tree offset; vbase = binfo_for_vbase (BINFO_TYPE (binfo), t); - offset = size_diffop (BINFO_OFFSET (vbase), BINFO_OFFSET (binfo)); - propagate_binfo_offsets (binfo, offset); + if (vbase != binfo) + { + offset = size_diffop (BINFO_OFFSET (vbase), BINFO_OFFSET (binfo)); + propagate_binfo_offsets (binfo, offset, t); + } } return NULL_TREE; @@ -4866,7 +4907,7 @@ layout_virtual_bases (t, offsets) if (is_empty_class (basetype)) layout_empty_base (vbase, size_int (CEIL (dsize, BITS_PER_UNIT)), - offsets); + offsets, t); else { tree offset; @@ -4877,7 +4918,7 @@ layout_virtual_bases (t, offsets) BINFO_OFFSET (vbase))); /* And compute the offset of the virtual base. */ - propagate_binfo_offsets (vbase, offset); + propagate_binfo_offsets (vbase, offset, t); /* Every virtual baseclass takes a least a UNIT, so that we can take it's address and get something different for each base. */ @@ -5055,7 +5096,7 @@ layout_class_type (t, empty_p, vfuns_p, /* Build FIELD_DECLs for all of the non-virtual base-types. */ empty_base_offsets = splay_tree_new (splay_tree_compare_integer_csts, NULL, NULL); - if (build_base_fields (rli, empty_p, empty_base_offsets)) + if (build_base_fields (rli, empty_p, empty_base_offsets, t)) CLASSTYPE_NEARLY_EMPTY_P (t) = 0; /* Add pointers to all of our virtual base-classes. */ @@ -5117,7 +5158,7 @@ layout_class_type (t, empty_p, vfuns_p, padding = NULL_TREE; layout_nonempty_base_or_field (rli, field, NULL_TREE, - empty_base_offsets); + empty_base_offsets, t); /* If we needed additional padding after this field, add it now. */ @@ -5134,7 +5175,7 @@ layout_class_type (t, empty_p, vfuns_p, DECL_USER_ALIGN (padding_field) = 0; layout_nonempty_base_or_field (rli, padding_field, NULL_TREE, - empty_base_offsets); + empty_base_offsets, t); } } @@ -6716,18 +6757,24 @@ get_vtbl_decl_for_binfo (binfo) return decl; } -/* Called from get_primary_binfo via dfs_walk. */ +/* Called from get_primary_binfo via dfs_walk. DATA is a TREE_LIST + who's TREE_PURPOSE is the TYPE of the required primary base and + who's TREE_VALUE is a list of candidate binfos that we fill in. */ static tree dfs_get_primary_binfo (binfo, data) tree binfo; void *data; { - tree primary_base = (tree) data; + tree cons = (tree) data; + tree primary_base = TREE_PURPOSE (cons); if (TREE_VIA_VIRTUAL (binfo) - && same_type_p (BINFO_TYPE (binfo), BINFO_TYPE (primary_base))) - return binfo; + && same_type_p (BINFO_TYPE (binfo), primary_base)) + /* This is the right type of binfo, but it might be an unshared + instance, and the shared instance is later in the dfs walk. We + must keep looking. */ + TREE_VALUE (cons) = tree_cons (NULL, binfo, TREE_VALUE (cons)); return NULL_TREE; } @@ -6745,7 +6792,8 @@ get_primary_binfo (binfo) { tree primary_base; tree result; - + tree virtuals; + primary_base = CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (binfo)); if (!primary_base) return NULL_TREE; @@ -6773,9 +6821,48 @@ get_primary_binfo (binfo) /* For a primary virtual base, we have to scan the entire hierarchy rooted at BINFO; the virtual base could be an indirect virtual - base. */ - result = dfs_walk (binfo, dfs_get_primary_binfo, NULL, primary_base); - my_friendly_assert (result != NULL_TREE, 20000730); + base. There could be more than one instance of the primary base + in the hierarchy, and if one is the canonical binfo we want that + one. If it exists, it should be the first one we find, but as a + consistency check we find them all and make sure. */ + virtuals = build_tree_list (BINFO_TYPE (primary_base), NULL_TREE); + dfs_walk (binfo, dfs_get_primary_binfo, NULL, virtuals); + virtuals = TREE_VALUE (virtuals); + + /* We must have found at least one instance. */ + my_friendly_assert (virtuals, 20010612); + + if (TREE_CHAIN (virtuals)) + { + /* We found more than one instance of the base. We must make + sure that, if one is the canonical one, it is the first one + we found. As the chain is in reverse dfs order, that means + the last on the list. */ + tree complete_binfo; + tree canonical; + + for (complete_binfo = binfo; + BINFO_INHERITANCE_CHAIN (complete_binfo); + complete_binfo = BINFO_INHERITANCE_CHAIN (complete_binfo)) + continue; + canonical = binfo_for_vbase (BINFO_TYPE (primary_base), + BINFO_TYPE (complete_binfo)); + + for (; virtuals; virtuals = TREE_CHAIN (virtuals)) + { + result = TREE_VALUE (virtuals); + + if (canonical == result) + { + /* This is the unshared instance. Make sure it was the + first one found. */ + my_friendly_assert (!TREE_CHAIN (virtuals), 20010612); + break; + } + } + } + else + result = TREE_VALUE (virtuals); return result; } @@ -7477,6 +7564,10 @@ accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, t, inits) BINFO_TYPE (orig_binfo)), 20000517); + /* If it doesn't have a vpte, we don't do anything. */ + if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo))) + return; + /* If we're building a construction vtable, we're not interested in subobjects that don't require construction vtables. */ if (ctor_vtbl_p @@ -7562,10 +7653,20 @@ dfs_accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, t, l) for (; b; b = BINFO_PRIMARY_BASE_OF (b)) { + tree probe; + + /* See if B is still within the hierarchy starting + at RTTI_BINFO. */ + for (probe = b; probe; + probe = BINFO_INHERITANCE_CHAIN (probe)) + if (probe == rtti_binfo) + break; + + if (!probe) + break; + primary = b; orig_primary = BINFO_PRIMARY_BASE_OF (orig_primary); - if (b == rtti_binfo) - break; } } else diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index b73626a3310..5da11ee3151 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1627,6 +1627,10 @@ struct lang_type inheritance is indicated by the absence of the other two flags, not by TREE_VIA_PRIVATE, which is unused. */ +/* Mark the binfo, whether shared or not. Each instance of a virtual + base can be separately marked. */ +#define BINFO_UNSHARED_MARKED(NODE) TREE_LANG_FLAG_0(NODE) + /* Nonzero means marked by DFS or BFS search, including searches by `get_binfo' and `get_base_distance'. */ #define BINFO_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLASSTYPE_MARKED(BINFO_TYPE(NODE)):TREE_LANG_FLAG_0(NODE)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index dfc4b53d9d6..01139ba0dc3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2001-06-12 Nathan Sidwell + + * g++.old-deja/g++.abi/vbase5.C: New test. + * g++.old-deja/g++.abi/vbase6.C: New test. + * g++.old-deja/g++.abi/vbase7.C: New test. + 2001-06-12 Kaveh R. Ghazi * gcc.c-torture/compile/20010610-1.c: New test. diff --git a/gcc/testsuite/g++.old-deja/g++.abi/vbase5.C b/gcc/testsuite/g++.old-deja/g++.abi/vbase5.C new file mode 100644 index 00000000000..6a3bbfbfb4b --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.abi/vbase5.C @@ -0,0 +1,22 @@ +// Build don't link: +// +// Copyright (C) 2001 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 12 Jun 2001 + +// 3130. A virtual base can have canonical and non-canonical instances +// of its primary. The canonical one should be first in dfs order. + +struct A +{ + virtual ~A (); +}; + +struct B +{ + virtual ~B (); +}; + + +struct C : virtual public A, virtual public B {}; +class D : public virtual C {}; +class E : public virtual C, public virtual D {}; diff --git a/gcc/testsuite/g++.old-deja/g++.abi/vbase6.C b/gcc/testsuite/g++.old-deja/g++.abi/vbase6.C new file mode 100644 index 00000000000..e8b959db32c --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.abi/vbase6.C @@ -0,0 +1,22 @@ +// Build don't link: +// +// Copyright (C) 2001 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 12 Jun 2001 + +// 3131. + +struct A +{ + virtual ~A (); +}; + +struct B +{ + virtual ~B (); +}; + + +struct C : virtual public B {}; +struct D : virtual public A, virtual public C {}; +struct E : public virtual C {}; +struct F : public virtual D, public virtual E {}; diff --git a/gcc/testsuite/g++.old-deja/g++.abi/vbase7.C b/gcc/testsuite/g++.old-deja/g++.abi/vbase7.C new file mode 100644 index 00000000000..5a4a3b5fdba --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.abi/vbase7.C @@ -0,0 +1,40 @@ +// Build don't run +// +// Copyright (C) 2001 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 12 Jun 2001 + +// 3132. A virtual thunk was missing. + +struct A +{ + int x; + virtual ~A() {} +}; + +struct B +{ + virtual ~B() { } +}; + + +struct C +{ + virtual ~C () {} +}; + + +struct D : public virtual A {}; +struct E : virtual public B, virtual public D {}; +struct F : virtual public C, virtual public E {}; +struct G : public virtual E {}; + +struct H : public virtual F, public virtual G +{ + virtual ~H (); +}; +H::~H() {} + +int main () +{ + return 0; +}