[patch] Problem with size of classes with vbases (TYPE_SIZE_UNIT problem)
Franz Sirl
Franz.Sirl-kernel@lauterbach.com
Sat May 30 00:50:00 GMT 1998
Hi,
this patch doesn't solve the "egcs-2.91.33: Corrupted assembler produced by g++"
problem I reported on egcs-bugs. So there seems to be another memory (stack?)
corruption bug. I have since verified this bug with.91.33/
egcs-2i586-pc-linux-gnulibc1. I've put HTMLView.ii.gz and HTMLView.s.gz on
< http://homepages.munich.netsurf.de/Franz.Sirl/misc/ >. Search for a label named
".Lfe39" (it was the same for i586 and powerpc) in the .s file and you will find
corrupted assembler shortly afterwards. I think it is meant to be a .bss
section.
Thanks,
Franz.
Am Sat, 30 May 1998 schrieb scott snyder:
>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++)
More information about the Gcc-bugs
mailing list