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] Problem with size of classes with vbases (TYPE_SIZE_UNIT problem)



hi -

This is relevant to egcs egcs-2.91.33 on a mips-sgi-irix6.2 platform.

I first noticed the problem with a construction like the following:

---------------------------------------------
#include <iostream>
#include <fstream>
#include <string>


int main ()
{
  ifstream* fh = new ifstream;
  fh->open ("/dev/null");
  string tok;

  getline (*fh, tok);
}
---------------------------------------------

When i run this, i get a core dump inside of malloc().

I tracked this down to a problem with new: it wasn't allocating
enough space, so when the ifstream constructor ran, it wrote past
the end of the block.

This can be seen by examining the assembly code produced for the
following program:

---------------------------------------
struct ios
{
  unsigned _strbuf;
};

struct fstreambase : virtual public ios {};

fstreambase* foo ()
{
  return new fstreambase;
}
---------------------------------------

sizeof (fstreambase) is 8, as expected.
But, here is the call to new, extracted from the assembly output:

        jal     $31,$25
        move    $3,$2
        move    $2,$3
        sw      $2,44($fp)
        li      $4,4                    # 0x4
        la      $25,__builtin_new

__builtin_new is called with an argument of 4.

The problem seems to have been introduced by the TYPE_SIZE_UNIT change
from a few weeks ago.  When the call to new is generated, the size used
comes from the TYPE_SIZE_UNIT field of the type, not TYPE_SIZE.
The size fields are normally computed in layout_type() -- this sets
both TYPE_SIZE and TYPE_SIZE_UNIT.  However, for C++ structs with
virtual bases, the size occupied by the vbases is added later,
in layout_basetypes().  This function alters TYPE_SIZE, but does
not alter TYPE_SIZE_UNIT to match.  Thus, when a structure is allocated,
the size of the block fails to account for any virtual bases.

Since TYPE_SIZE_UNIT appears to be a recent addition, it's plausible
that this may have been overlooked.

The appended patch seems to fix this, and doesn't cause any new
regressions.

thanks,
sss


1998-05-29  scott snyder  <snyder@d0sgif.fnal.gov>

	* tree.c (layout_basetypes): If we change TYPE_SIZE, change
	TYPE_SIZE_UNIT too.

Index: cp/tree.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/tree.c,v
retrieving revision 1.43
diff -u -p -c -r1.43 tree.c
diff: conflicting specifications of output style
*** tree.c      1998/05/24 23:57:45     1.43
--- tree.c      1998/05/29 20:11:21
*************** layout_basetypes (rec, max)
*** 722,728 ****
     here, as that is for this class, without any virtual base classes.  */
    TYPE_ALIGN (rec) = record_align;
    if (const_size != nonvirtual_const_size)
!     TYPE_SIZE (rec) = size_int (const_size);
  
    /* Now propagate offset information throughout the lattice.  */
    for (i = 0; i < n_baseclasses; i++)
--- 722,732 ----
     here, as that is for this class, without any virtual base classes.  */
    TYPE_ALIGN (rec) = record_align;
    if (const_size != nonvirtual_const_size)
!     {
!       TYPE_SIZE (rec) = size_int (const_size);
!       TYPE_SIZE_UNIT (rec) = size_binop (FLOOR_DIV_EXPR, TYPE_SIZE (rec),
!                                          size_int (BITS_PER_UNIT));
!     }
  
    /* Now propagate offset information throughout the lattice.  */
    for (i = 0; i < n_baseclasses; i++)


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