This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH for vtable bug on alpha
- To: egcs-patches at cygnus dot com
- Subject: PATCH for vtable bug on alpha
- From: Mark Mitchell <mark at markmitchell dot com>
- Date: Wed, 7 Oct 1998 02:13:35 -0700
- Cc: Richard Henderson <rth at cygnus dot com>, Jason Merrill <jason at cygnus dot com>
- Reply-to: mark at markmitchell dot com
Richard --
I think this patch should fix the problem you reported earlier. At
least, it seemed to on my x86-linux-gnu -> alpha-linux-gnu cross
compiler. Please let me know if it works for you.
This patch changes the type of the vtbl pointer a class from:
void (* (*)[N])()
(i.e., pointer-to-array-of-N-function-pointers) to
void (**)()
(i.e., pointer-to-pointer-to-function) which is almost the same type,
but is the same in all classes.
--
Mark Mitchell mark@markmitchell.com
Mark Mitchell Consulting http://www.markmitchell.com
1998-10-07 Mark Mitchell <mark@markmitchell.com>
* cp-tree.h (vtbl_ptr_type_node): New variable.
* class.c (build_vtbl_ref): Don't indirect through the vptr; it's
already of the right type.
(finish_struct_1): Make the vptr be of type vtbl_ptr_type_node.
Simplify code to grow vtable.
* decl.c (vtbl_ptr_type_node): Define.
(init_decl_processing): Initialize it.
Index: class.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/class.c,v
retrieving revision 1.89
diff -c -p -r1.89 class.c
*** class.c 1998/10/06 14:19:49 1.89
--- class.c 1998/10/07 09:03:31
*************** build_vtbl_ref (instance, idx)
*** 501,508 ****
basetype = TREE_TYPE (basetype);
if (instance == current_class_ref)
! vtbl = build_indirect_ref (build_vfield_ref (instance, basetype),
! NULL_PTR);
else
{
if (optimize)
--- 501,507 ----
basetype = TREE_TYPE (basetype);
if (instance == current_class_ref)
! vtbl = build_vfield_ref (instance, basetype);
else
{
if (optimize)
*************** build_vtbl_ref (instance, idx)
*** 542,549 ****
|| TREE_CODE (instance) == VAR_DECL))
vtbl = TYPE_BINFO_VTABLE (basetype);
else
! vtbl = build_indirect_ref (build_vfield_ref (instance, basetype),
! NULL_PTR);
}
assemble_external (vtbl);
--- 541,547 ----
|| TREE_CODE (instance) == VAR_DECL))
vtbl = TYPE_BINFO_VTABLE (basetype);
else
! vtbl = build_vfield_ref (instance, basetype);
}
assemble_external (vtbl);
*************** finish_struct_1 (t, warn_anon)
*** 3782,3788 ****
/* We build this decl with ptr_type_node, and
change the type when we know what it should be. */
vfield = build_lang_field_decl (FIELD_DECL, get_vfield_name (t),
! ptr_type_node);
/* If you change any of the below, take a look at all the
other VFIELD_BASEs and VTABLE_BASEs in the code, and change
them too. */
--- 3780,3786 ----
/* We build this decl with ptr_type_node, and
change the type when we know what it should be. */
vfield = build_lang_field_decl (FIELD_DECL, get_vfield_name (t),
! vtbl_ptr_type_node);
/* If you change any of the below, take a look at all the
other VFIELD_BASEs and VTABLE_BASEs in the code, and change
them too. */
*************** finish_struct_1 (t, warn_anon)
*** 4090,4127 ****
/* Now lay out the virtual function table. */
if (has_virtual)
{
! tree atype, itype;
! if (TREE_TYPE (vfield) == ptr_type_node)
! {
! /* We must create a pointer to this table because
! the one inherited from base class does not exist.
! We will fill in the type when we know what it
! should really be. Use `size_int' so values are memoized
! in common cases. */
! itype = build_index_type (size_int (has_virtual));
! atype = build_array_type (vtable_entry_type, itype);
! layout_type (atype);
! TREE_TYPE (vfield) = build_pointer_type (atype);
! }
! else
! {
! atype = TREE_TYPE (TREE_TYPE (vfield));
- if (has_virtual != TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (atype))))
- {
- /* We must extend (or create) the boundaries on this array,
- because we picked up virtual functions from multiple
- base classes. */
- itype = build_index_type (size_int (has_virtual));
- atype = build_array_type (vtable_entry_type, itype);
- layout_type (atype);
- vfield = copy_node (vfield);
- TREE_TYPE (vfield) = build_pointer_type (atype);
- }
- }
-
CLASSTYPE_VFIELD (t) = vfield;
if (TREE_TYPE (TYPE_BINFO_VTABLE (t)) != atype)
{
TREE_TYPE (TYPE_BINFO_VTABLE (t)) = atype;
--- 4088,4102 ----
/* Now lay out the virtual function table. */
if (has_virtual)
{
! /* Use size_int so values are memoized in common cases. */
! tree itype = build_index_type (size_int (has_virtual));
! tree atype = build_array_type (vtable_entry_type, itype);
! layout_type (atype);
CLASSTYPE_VFIELD (t) = vfield;
+
+ /* We may have to grow the vtable. */
if (TREE_TYPE (TYPE_BINFO_VTABLE (t)) != atype)
{
TREE_TYPE (TYPE_BINFO_VTABLE (t)) = atype;
Index: cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.146
diff -c -p -r1.146 cp-tree.h
*** cp-tree.h 1998/10/06 14:19:48 1.146
--- cp-tree.h 1998/10/07 09:03:43
*************** extern tree opaque_type_node, signature_
*** 1931,1938 ****
#define vfunc_ptr_type_node \
(flag_vtable_thunks ? vtable_entry_type : ptr_type_node)
! /* Array type `(void *)[]' */
extern tree vtbl_type_node;
extern tree delta_type_node;
extern tree std_node;
--- 1931,1940 ----
#define vfunc_ptr_type_node \
(flag_vtable_thunks ? vtable_entry_type : ptr_type_node)
! /* The type of a vtbl, i.e., an array of vtable entries. */
extern tree vtbl_type_node;
+ /* The type of a class vtbl pointer, i.e., a pointer to a vtable entry. */
+ extern tree vtbl_ptr_type_node;
extern tree delta_type_node;
extern tree std_node;
Index: decl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl.c,v
retrieving revision 1.223
diff -c -p -r1.223 decl.c
*** decl.c 1998/10/06 14:19:51 1.223
--- decl.c 1998/10/07 09:04:34
*************** tree sigtable_entry_type;
*** 329,334 ****
--- 329,335 ----
/* Array type `vtable_entry_type[]' */
tree vtbl_type_node;
+ tree vtbl_ptr_type_node;
/* namespace std */
tree std_node;
*************** init_decl_processing ()
*** 6148,6153 ****
--- 6149,6157 ----
layout_type (vtbl_type_node);
vtbl_type_node = cp_build_type_variant (vtbl_type_node, 1, 0);
record_builtin_type (RID_MAX, NULL_PTR, vtbl_type_node);
+ vtbl_ptr_type_node = build_pointer_type (vtable_entry_type);
+ layout_type (vtbl_ptr_type_node);
+ record_builtin_type (RID_MAX, NULL_PTR, vtbl_ptr_type_node);
/* Simplify life by making a "sigtable_entry_type". Give its
fields names so that the debugger can use them. */