This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: fix order of vtable group under the new ABI
- To: gcc-patches at gcc dot gnu dot org
- Subject: C++ PATCH: fix order of vtable group under the new ABI
- From: Mark Mitchell <mark at codesourcery dot com>
- Date: Wed, 22 Mar 2000 13:50:17 -0800
- Reply-to: mark at codesourcery dot com
Under the new ABI, primary and secondary vtables are laid out
contiguously. Virtual base vtables have to follow primary base
vtables; we were getting that wrong. Here's the fix.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
2000-03-22 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (BINFO_FOR_VBASE): Adjust documentation.
(CANONICAL_BINFO): New macro.
(BINFO_NEW_VTABLE_MARKED): Use it.
(SET_BINFO_NEW_VTABLE_MARKED): Likewise.
(CLEAR_BINFO_NEW_VTABLE_MARKED): Likewise.
* class.c (dfs_build_vbase_offset_vtbl_entries): Use BINFO_TYPE,
not TREE_TYPE.
(build_primary_vtable): Adjust usage of BINFO_NEW_VTABLE_MARKED.
(build_secondary_vtable): Likewise.
(dfs_finish_vtbls): Likewise.
(dfs_accumulate_vtbl_inits): Likewise.
(accumulate_vtbl_inits): New function.
(finish_vtbls): Make sure that virtual bases come after
non-virtual bases in the vtable group.
(record_base_offsets): Don't save and restore TREE_VIA_VIRTUAL.
(finish_struct_1): Adjust usage of BINFO_NEW_VTABLE_MARKED.
* search.c (struct vbase_info): Move definition.
(marked_new_vtable_p): Adjust usage of BINFO_NEW_VTABLE_MARKED.
(unmarked_new_vtable_p): Likewise.
(dfs_mark_vtable_path): Remove.
(dfs_mark_new_vtable): Remove.
(dfs_unmark_new_vtable): Likewise.
(dfs_clear_search_slot): Likewise.
(dfs_find_vbases): Adjust usage of BINFO_NEW_VTABLE_MARKED.
(dfs_clear_vbase_slots): Likewise.
(init_vbase_pointers): LIkewise.
Index: testsuite/g++.old-deja/g++.abi/vtable.C
===================================================================
RCS file: vtable.C
diff -N vtable.C
*** /dev/null Tue May 5 13:32:27 1998
--- vtable.C Wed Mar 22 13:37:11 2000
***************
*** 0 ****
--- 1,82 ----
+ // Test various aspects of vtable layout.
+ // Special g++ Options: -fno-strict-aliasing
+ // Origin: Mark Mitchell <mark@codesourcery.com>
+
+ #if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
+
+ struct S0
+ {
+ virtual void h ()
+ {
+ }
+
+ int k;
+ };
+
+
+ struct S1
+ {
+ virtual void f ()
+ {
+ }
+
+ int i;
+ };
+
+ struct S2 : virtual public S0
+ {
+ virtual void g ()
+ {
+ }
+
+ int j;
+ };
+
+ struct S3
+ {
+ virtual void k ()
+ {
+ }
+
+ int l;
+ };
+
+ struct S4 : public virtual S1, public S2, public S3
+ {
+ };
+
+ inline void* vtable (void *object)
+ {
+ // The vptr is always the first part of the object.
+ return * (void **) object;
+ }
+
+ int main ()
+ {
+ // The vtable layout order for S4 should consist of S4's primary
+ // vtable (shared with S2), followed by the vtable for S3 (because
+ // it is a non-virtual base). Then, these should be followed by the
+ // the vtables for S1 and S0, which are virtual.
+ S4 s4;
+ S0 *s0 = &s4;
+ S1 *s1 = &s4;
+ S2 *s2 = &s4;
+ S3 *s3 = &s4;
+
+ if (vtable (&s4) != vtable (s2))
+ return 1;
+ if (vtable (s2) >= vtable (s3))
+ return 2;
+ if (vtable (s3) >= vtable (s1))
+ return 3;
+ if (vtable (s1) >= vtable (s0))
+ return 4;
+ }
+
+ #else /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
+
+ int main ()
+ {
+ }
+
+ #endif /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/class.c,v
retrieving revision 1.277
diff -c -p -r1.277 class.c
*** class.c 2000/03/22 05:39:34 1.277
--- class.c 2000/03/22 21:37:15
*************** static tree dfs_search_base_offsets PARA
*** 161,166 ****
--- 161,167 ----
static int layout_conflict_p PARAMS ((tree, varray_type));
static unsigned HOST_WIDE_INT end_of_class PARAMS ((tree, int));
static void layout_empty_base PARAMS ((tree, tree, varray_type));
+ static void accumulate_vtbl_inits PARAMS ((tree, tree));
/* Variables shared between class.c and call.c. */
*************** dfs_build_vbase_offset_vtbl_entries (bin
*** 276,282 ****
/* Remember the index to the vbase offset for this virtual
base. */
! vbase = BINFO_FOR_VBASE (TREE_TYPE (binfo), TREE_PURPOSE (list));
if (!TREE_VALUE (list))
BINFO_VPTR_FIELD (vbase) = build_int_2 (-1, 0);
else
--- 277,283 ----
/* Remember the index to the vbase offset for this virtual
base. */
! vbase = BINFO_FOR_VBASE (BINFO_TYPE (binfo), TREE_PURPOSE (list));
if (!TREE_VALUE (list))
BINFO_VPTR_FIELD (vbase) = build_int_2 (-1, 0);
else
*************** build_primary_vtable (binfo, type)
*** 1072,1078 ****
{
tree offset;
! if (BINFO_NEW_VTABLE_MARKED (binfo))
/* We have already created a vtable for this base, so there's
no need to do it again. */
return 0;
--- 1073,1079 ----
{
tree offset;
! if (BINFO_NEW_VTABLE_MARKED (binfo, type))
/* We have already created a vtable for this base, so there's
no need to do it again. */
return 0;
*************** build_primary_vtable (binfo, type)
*** 1106,1112 ****
TYPE_BINFO_VIRTUALS (type) = virtuals;
binfo = TYPE_BINFO (type);
! SET_BINFO_NEW_VTABLE_MARKED (binfo);
return 1;
}
--- 1107,1113 ----
TYPE_BINFO_VIRTUALS (type) = virtuals;
binfo = TYPE_BINFO (type);
! SET_BINFO_NEW_VTABLE_MARKED (binfo, type);
return 1;
}
*************** build_secondary_vtable (binfo, for_type)
*** 1147,1160 ****
current_class_type),
170);
! if (BINFO_NEW_VTABLE_MARKED (binfo))
/* We already created a vtable for this base. There's no need to
do it again. */
return 0;
/* Remember that we've created a vtable for this BINFO, so that we
don't try to do so again. */
! SET_BINFO_NEW_VTABLE_MARKED (binfo);
/* Make fresh virtual list, so we can smash it later. */
BINFO_VIRTUALS (binfo) = copy_list (BINFO_VIRTUALS (binfo));
--- 1148,1161 ----
current_class_type),
170);
! if (BINFO_NEW_VTABLE_MARKED (binfo, current_class_type))
/* We already created a vtable for this base. There's no need to
do it again. */
return 0;
/* Remember that we've created a vtable for this BINFO, so that we
don't try to do so again. */
! SET_BINFO_NEW_VTABLE_MARKED (binfo, current_class_type);
/* Make fresh virtual list, so we can smash it later. */
BINFO_VIRTUALS (binfo) = copy_list (BINFO_VIRTUALS (binfo));
*************** dfs_finish_vtbls (binfo, data)
*** 2760,2772 ****
tree binfo;
void *data;
{
if (!BINFO_PRIMARY_MARKED_P (binfo)
&& CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))
! && BINFO_NEW_VTABLE_MARKED (binfo))
initialize_vtable (binfo,
! build_vtbl_initializer (binfo, (tree) data));
! CLEAR_BINFO_NEW_VTABLE_MARKED (binfo);
SET_BINFO_MARKED (binfo);
return NULL_TREE;
--- 2761,2775 ----
tree binfo;
void *data;
{
+ tree t = (tree) data;
+
if (!BINFO_PRIMARY_MARKED_P (binfo)
&& CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))
! && BINFO_NEW_VTABLE_MARKED (binfo, t))
initialize_vtable (binfo,
! build_vtbl_initializer (binfo, t));
! CLEAR_BINFO_NEW_VTABLE_MARKED (binfo, t);
SET_BINFO_MARKED (binfo);
return NULL_TREE;
*************** dfs_accumulate_vtbl_inits (binfo, data)
*** 2781,2795 ****
tree binfo;
void *data;
{
if (!BINFO_PRIMARY_MARKED_P (binfo)
&& CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))
! && BINFO_NEW_VTABLE_MARKED (binfo))
{
- tree l;
- tree t;
-
- l = (tree) data;
- t = TREE_PURPOSE (l);
/* If this is a secondary vtable, record its location. */
if (binfo != TYPE_BINFO (t))
--- 2784,2799 ----
tree binfo;
void *data;
{
+ tree l;
+ tree t;
+
+ l = (tree) data;
+ t = TREE_PURPOSE (l);
+
if (!BINFO_PRIMARY_MARKED_P (binfo)
&& CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))
! && BINFO_NEW_VTABLE_MARKED (binfo, t))
{
/* If this is a secondary vtable, record its location. */
if (binfo != TYPE_BINFO (t))
*************** dfs_accumulate_vtbl_inits (binfo, data)
*** 2807,2825 ****
size_int (list_length (TREE_VALUE (l)))));
}
! /* Add the initializers for this vtable to the initailizers for
the other vtables we've already got. */
TREE_VALUE (l)
= chainon (TREE_VALUE (l),
build_vtbl_initializer (binfo, t));
}
! CLEAR_BINFO_NEW_VTABLE_MARKED (binfo);
! SET_BINFO_MARKED (binfo);
return NULL_TREE;
}
/* Create all the necessary vtables for T and its base classes. */
static void
--- 2811,2844 ----
size_int (list_length (TREE_VALUE (l)))));
}
! /* Add the initializers for this vtable to the initializers for
the other vtables we've already got. */
TREE_VALUE (l)
= chainon (TREE_VALUE (l),
build_vtbl_initializer (binfo, t));
}
! CLEAR_BINFO_NEW_VTABLE_MARKED (binfo, t);
return NULL_TREE;
}
+ /* Add the vtbl initializers for BINFO (and its non-primary,
+ non-virtual bases) to the list of INITS. */
+
+ static void
+ accumulate_vtbl_inits (binfo, inits)
+ tree binfo;
+ tree inits;
+ {
+ /* Walk the BINFO and its bases. */
+ dfs_walk_real (binfo,
+ dfs_accumulate_vtbl_inits,
+ NULL,
+ dfs_skip_vbases,
+ inits);
+ }
+
/* Create all the necessary vtables for T and its base classes. */
static void
*************** finish_vtbls (t)
*** 2829,2854 ****
if (merge_primary_and_secondary_vtables_p ())
{
tree list;
/* Under the new ABI, we lay out the primary and secondary
vtables in one contiguous vtable. The primary vtable is
! first, followed by the secondary vtables as encountered in a
! pre-order depth-first left-to-right traversal. */
list = build_tree_list (t, NULL_TREE);
! dfs_walk_real (TYPE_BINFO (t),
! dfs_accumulate_vtbl_inits,
! NULL,
! dfs_unmarked_real_bases_queue_p,
! list);
if (TYPE_BINFO_VTABLE (t))
initialize_vtable (TYPE_BINFO (t), TREE_VALUE (list));
}
else
! dfs_walk (TYPE_BINFO (t), dfs_finish_vtbls,
! dfs_unmarked_real_bases_queue_p, t);
!
! dfs_walk (TYPE_BINFO (t), dfs_unmark,
! dfs_marked_real_bases_queue_p, t);
}
/* True if we should override the given BASE_FNDECL with the given
--- 2848,2878 ----
if (merge_primary_and_secondary_vtables_p ())
{
tree list;
+ tree vbase;
/* Under the new ABI, we lay out the primary and secondary
vtables in one contiguous vtable. The primary vtable is
! first, followed by the non-virtual secondary vtables in
! inheritance graph order. */
list = build_tree_list (t, NULL_TREE);
! accumulate_vtbl_inits (TYPE_BINFO (t), list);
! /* Then come the virtual bases, also in inheritance graph
! order. */
! for (vbase = CLASSTYPE_VBASECLASSES (t);
! vbase;
! vbase = TREE_CHAIN (vbase))
! accumulate_vtbl_inits (vbase, list);
!
if (TYPE_BINFO_VTABLE (t))
initialize_vtable (TYPE_BINFO (t), TREE_VALUE (list));
}
else
! {
! dfs_walk (TYPE_BINFO (t), dfs_finish_vtbls,
! dfs_unmarked_real_bases_queue_p, t);
! dfs_walk (TYPE_BINFO (t), dfs_unmark,
! dfs_marked_real_bases_queue_p, t);
! }
}
/* True if we should override the given BASE_FNDECL with the given
*************** record_base_offsets (binfo, base_offsets
*** 4142,4158 ****
tree binfo;
varray_type *base_offsets;
{
- int virtual_p;
-
- /* If BINFO is virtual, we still want to mention its offset in
- BASE_OFFSETS. */
- virtual_p = TREE_VIA_VIRTUAL (binfo);
- TREE_VIA_VIRTUAL (binfo) = 0;
dfs_walk (binfo,
dfs_record_base_offsets,
dfs_skip_vbases,
base_offsets);
- TREE_VIA_VIRTUAL (binfo) = virtual_p;
}
/* Returns non-NULL if there is already an entry in DATA (which is
--- 4166,4175 ----
*************** finish_struct_1 (t)
*** 5308,5314 ****
}
build_primary_vtable (NULL_TREE, t);
}
! else if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t)))
/* Here we know enough to change the type of our virtual
function table, but we will wait until later this function. */
build_primary_vtable (CLASSTYPE_PRIMARY_BINFO (t), t);
--- 5325,5331 ----
}
build_primary_vtable (NULL_TREE, t);
}
! else if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t), t))
/* Here we know enough to change the type of our virtual
function table, but we will wait until later this function. */
build_primary_vtable (CLASSTYPE_PRIMARY_BINFO (t), t);
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.424
diff -c -p -r1.424 cp-tree.h
*** cp-tree.h 2000/03/22 01:32:09 1.424
--- cp-tree.h 2000/03/22 21:37:19
*************** struct lang_type
*** 1566,1575 ****
(also distinct from the copies in the TYPE_BINFO hierarchy.) */
#define CLASSTYPE_VBASECLASSES(NODE) (TYPE_LANG_SPECIFIC(NODE)->vbases)
! /* The BINFO (if any) for the virtual baseclass T of the class C. */
#define BINFO_FOR_VBASE(T, C) \
(binfo_member (T, CLASSTYPE_VBASECLASSES (C)))
/* Number of direct baseclasses of NODE. */
#define CLASSTYPE_N_BASECLASSES(NODE) \
(BINFO_N_BASETYPES (TYPE_BINFO (NODE)))
--- 1566,1584 ----
(also distinct from the copies in the TYPE_BINFO hierarchy.) */
#define CLASSTYPE_VBASECLASSES(NODE) (TYPE_LANG_SPECIFIC(NODE)->vbases)
! /* The BINFO (if any) for the virtual baseclass T of the class C from
! the CLASSTYPE_VBASECLASSES list. */
#define BINFO_FOR_VBASE(T, C) \
(binfo_member (T, CLASSTYPE_VBASECLASSES (C)))
+ /* For a non-virtual BINFO, the BINFO itself; for a virtual BINFO, the
+ BINFO_FOR_VBASE. C is the most derived class for the hierarchy
+ containing BINFO. */
+ #define CANONICAL_BINFO(BINFO, C) \
+ (TREE_VIA_VIRTUAL (BINFO) \
+ ? BINFO_FOR_VBASE (BINFO_TYPE (BINFO), C) \
+ : BINFO)
+
/* Number of direct baseclasses of NODE. */
#define CLASSTYPE_N_BASECLASSES(NODE) \
(BINFO_N_BASETYPES (TYPE_BINFO (NODE)))
*************** struct lang_type
*** 1704,1714 ****
#define SET_BINFO_VTABLE_PATH_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?SET_CLASSTYPE_MARKED3(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_3(NODE)=1))
#define CLEAR_BINFO_VTABLE_PATH_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLEAR_CLASSTYPE_MARKED3(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_3(NODE)=0))
! /* Nonzero means that this class has a new vtable. */
! #define BINFO_NEW_VTABLE_MARKED(NODE) \
! (TREE_VIA_VIRTUAL(NODE)?CLASSTYPE_MARKED4(BINFO_TYPE(NODE)):TREE_LANG_FLAG_4(NODE))
! #define SET_BINFO_NEW_VTABLE_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?SET_CLASSTYPE_MARKED4(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_4(NODE)=1))
! #define CLEAR_BINFO_NEW_VTABLE_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLEAR_CLASSTYPE_MARKED4(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_4(NODE)=0))
/* Nonzero means this class has done dfs_pushdecls. */
#define BINFO_PUSHDECLS_MARKED(NODE) BINFO_VTABLE_PATH_MARKED (NODE)
--- 1713,1726 ----
#define SET_BINFO_VTABLE_PATH_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?SET_CLASSTYPE_MARKED3(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_3(NODE)=1))
#define CLEAR_BINFO_VTABLE_PATH_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLEAR_CLASSTYPE_MARKED3(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_3(NODE)=0))
! /* Nonzero means B (a BINFO) needs a new vtable. B is part of the
! hierarchy dominated by C. */
! #define BINFO_NEW_VTABLE_MARKED(B, C) \
! (TREE_LANG_FLAG_4 (CANONICAL_BINFO (B, C)))
! #define SET_BINFO_NEW_VTABLE_MARKED(B, C) \
! (BINFO_NEW_VTABLE_MARKED (B, C) = 1)
! #define CLEAR_BINFO_NEW_VTABLE_MARKED(B, C) \
! (BINFO_NEW_VTABLE_MARKED (B, C) = 0)
/* Nonzero means this class has done dfs_pushdecls. */
#define BINFO_PUSHDECLS_MARKED(NODE) BINFO_VTABLE_PATH_MARKED (NODE)
Index: cp/search.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/search.c,v
retrieving revision 1.165
diff -c -p -r1.165 search.c
*** search.c 2000/03/22 01:32:09 1.165
--- search.c 2000/03/22 21:37:21
*************** pop_stack_level (stack)
*** 76,81 ****
--- 76,90 ----
#define search_level stack_level
static struct search_level *search_stack;
+ struct vbase_info
+ {
+ /* The class dominating the hierarchy. */
+ tree type;
+ tree decl_ptr;
+ tree inits;
+ tree vbase_types;
+ };
+
static tree next_baselink PARAMS ((tree));
static tree get_vbase_1 PARAMS ((tree, tree, unsigned int *));
static tree lookup_field_1 PARAMS ((tree, tree));
*************** unmarked_vtable_pathp (binfo, data)
*** 2537,2553 ****
static tree
marked_new_vtablep (binfo, data)
tree binfo;
! void *data ATTRIBUTE_UNUSED;
{
! return BINFO_NEW_VTABLE_MARKED (binfo) ? binfo : NULL_TREE;
}
static tree
unmarked_new_vtablep (binfo, data)
tree binfo;
! void *data ATTRIBUTE_UNUSED;
{
! return !BINFO_NEW_VTABLE_MARKED (binfo) ? binfo : NULL_TREE;
}
static tree
--- 2546,2566 ----
static tree
marked_new_vtablep (binfo, data)
tree binfo;
! void *data;
{
! struct vbase_info *vi = (struct vbase_info *) data;
!
! return BINFO_NEW_VTABLE_MARKED (binfo, vi->type) ? binfo : NULL_TREE;
}
static tree
unmarked_new_vtablep (binfo, data)
tree binfo;
! void *data;
{
! struct vbase_info *vi = (struct vbase_info *) data;
!
! return !BINFO_NEW_VTABLE_MARKED (binfo, vi->type) ? binfo : NULL_TREE;
}
static tree
*************** dfs_vtable_path_unmark (binfo, data)
*** 2614,2644 ****
return NULL_TREE;
}
- #if 0
- static void
- dfs_mark_vtable_path (binfo) tree binfo;
- { SET_BINFO_VTABLE_PATH_MARKED (binfo); }
-
- static void
- dfs_mark_new_vtable (binfo) tree binfo;
- { SET_BINFO_NEW_VTABLE_MARKED (binfo); }
-
- static void
- dfs_unmark_new_vtable (binfo) tree binfo;
- { CLEAR_BINFO_NEW_VTABLE_MARKED (binfo); }
-
- static void
- dfs_clear_search_slot (binfo) tree binfo;
- { CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (binfo)) = 0; }
- #endif
- struct vbase_info
- {
- tree decl_ptr;
- tree inits;
- tree vbase_types;
- };
-
/* Attach to the type of the virtual base class, the pointer to the
virtual base class. */
--- 2627,2633 ----
*************** dfs_find_vbases (binfo, data)
*** 2668,2674 ****
}
}
SET_BINFO_VTABLE_PATH_MARKED (binfo);
! SET_BINFO_NEW_VTABLE_MARKED (binfo);
return NULL_TREE;
}
--- 2657,2663 ----
}
}
SET_BINFO_VTABLE_PATH_MARKED (binfo);
! SET_BINFO_NEW_VTABLE_MARKED (binfo, vi->type);
return NULL_TREE;
}
*************** dfs_init_vbase_pointers (binfo, data)
*** 2737,2748 ****
static tree
dfs_clear_vbase_slots (binfo, data)
tree binfo;
! void *data ATTRIBUTE_UNUSED;
{
tree type = BINFO_TYPE (binfo);
CLASSTYPE_SEARCH_SLOT (type) = 0;
CLEAR_BINFO_VTABLE_PATH_MARKED (binfo);
! CLEAR_BINFO_NEW_VTABLE_MARKED (binfo);
return NULL_TREE;
}
--- 2726,2739 ----
static tree
dfs_clear_vbase_slots (binfo, data)
tree binfo;
! void *data;
{
tree type = BINFO_TYPE (binfo);
+ struct vbase_info *vi = (struct vbase_info *) data;
+
CLASSTYPE_SEARCH_SLOT (type) = 0;
CLEAR_BINFO_VTABLE_PATH_MARKED (binfo);
! CLEAR_BINFO_NEW_VTABLE_MARKED (binfo, vi->type);
return NULL_TREE;
}
*************** init_vbase_pointers (type, decl_ptr)
*** 2760,2765 ****
--- 2751,2757 ----
/* Find all the virtual base classes, marking them for later
initialization. */
+ vi.type = type;
vi.decl_ptr = decl_ptr;
vi.vbase_types = CLASSTYPE_VBASECLASSES (type);
vi.inits = NULL_TREE;
*************** init_vbase_pointers (type, decl_ptr)
*** 2773,2779 ****
marked_vtable_pathp,
&vi);
! dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep, 0);
flag_this_is_variable = old_flag;
return vi.inits;
}
--- 2765,2771 ----
marked_vtable_pathp,
&vi);
! dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep, &vi);
flag_this_is_variable = old_flag;
return vi.inits;
}
*************** expand_indirect_vtbls_init (binfo, decl_
*** 3088,3099 ****
{
tree vbases = CLASSTYPE_VBASECLASSES (type);
struct vbase_info vi;
vi.decl_ptr = decl_ptr;
vi.vbase_types = vbases;
dfs_walk (binfo, dfs_find_vbases, unmarked_new_vtablep, &vi);
fixup_all_virtual_upcast_offsets (type, vi.decl_ptr);
! dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep, 0);
}
}
--- 3080,3092 ----
{
tree vbases = CLASSTYPE_VBASECLASSES (type);
struct vbase_info vi;
+ vi.type = type;
vi.decl_ptr = decl_ptr;
vi.vbase_types = vbases;
dfs_walk (binfo, dfs_find_vbases, unmarked_new_vtablep, &vi);
fixup_all_virtual_upcast_offsets (type, vi.decl_ptr);
! dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep, &vi);
}
}