C++ PATCH: correct layout of empty bases in the new ABI

Mark Mitchell mark@codesourcery.com
Mon Jan 24 22:29:00 GMT 2000


When we have an empty class, we temporarily add an unnamed `char'
member so that the class will not get a zero size. (C++ requires that
all structures have non-zero size).  However, under the new ABI, we
can have an empty class with baseclasses, and the baseclasses need to
remain at offset zero.  We weren't handling this correctly. 

Here's the fix.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

2000-01-24  Mark Mitchell  <mark@codesourcery.com>

	* class.c (layout_class_type): Put the fields required to make a
	class non-empty at the end, not the beginning, of the TYPE_FIELDs
	list.

Index: class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/class.c,v
retrieving revision 1.243
diff -c -p -r1.243 class.c
*** class.c	2000/01/24 10:59:02	1.243
--- class.c	2000/01/25 06:26:46
*************** layout_class_type (t, empty_p, has_virtu
*** 4688,4693 ****
--- 4688,4695 ----
       tree *new_virtuals_p;
       tree *overridden_virtuals_p;
  {
+   tree padding = NULL_TREE;
+ 
    /* If possible, we reuse the virtual function table pointer from one
       of our base classes.  */
    determine_primary_base (t, has_virtual_p);
*************** layout_class_type (t, empty_p, has_virtu
*** 4712,4726 ****
       have non-zero size.  The field that we add here is fake, in the
       sense that, for example, we don't want people to be able to
       initialize it later.  So, we add it just long enough to let the
!      back-end lay out the type, and then remove it.  */
    if (*empty_p)
      {
!       tree decl = build_lang_decl
! 	(FIELD_DECL, NULL_TREE, char_type_node);
!       TREE_CHAIN (decl) = TYPE_FIELDS (t);
!       TYPE_FIELDS (t) = decl;
        TYPE_NONCOPIED_PARTS (t) 
! 	= tree_cons (NULL_TREE, decl, TYPE_NONCOPIED_PARTS (t));
        TREE_STATIC (TYPE_NONCOPIED_PARTS (t)) = 1;
      }
  
--- 4714,4730 ----
       have non-zero size.  The field that we add here is fake, in the
       sense that, for example, we don't want people to be able to
       initialize it later.  So, we add it just long enough to let the
!      back-end lay out the type, and then remove it.  In the new ABI,
!      the class may be empty even if it has basetypes.  Therefore, we
!      add the fake field at the end of the fields list; if there are
!      already FIELD_DECLs on the list, their offsets will not be
!      disturbed.  */
    if (*empty_p)
      {
!       padding = build_lang_decl (FIELD_DECL, NULL_TREE, char_type_node);
!       TYPE_FIELDS (t) = chainon (TYPE_FIELDS (t), padding);
        TYPE_NONCOPIED_PARTS (t) 
! 	= tree_cons (NULL_TREE, padding, TYPE_NONCOPIED_PARTS (t));
        TREE_STATIC (TYPE_NONCOPIED_PARTS (t)) = 1;
      }
  
*************** layout_class_type (t, empty_p, has_virtu
*** 4734,4740 ****
    /* If we added an extra field to make this class non-empty, remove
       it now.  */
    if (*empty_p)
!     TYPE_FIELDS (t) = TREE_CHAIN (TYPE_FIELDS (t));
  
    /* Delete all zero-width bit-fields from the list of fields.  Now
       that the type is laid out they are no longer important.  */
--- 4738,4751 ----
    /* If we added an extra field to make this class non-empty, remove
       it now.  */
    if (*empty_p)
!     {
!       tree *declp;
! 
!       declp = &TYPE_FIELDS (t);
!       while (*declp != padding)
! 	declp = &TREE_CHAIN (*declp);
!       *declp = TREE_CHAIN (*declp);
!     }
  
    /* Delete all zero-width bit-fields from the list of fields.  Now
       that the type is laid out they are no longer important.  */


More information about the Gcc-patches mailing list