This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

PATCH for vtable bug on alpha



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.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]