bug-gplusplus
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Optimization bug in g++-3.3.3


From: Kenneth Duda
Subject: Optimization bug in g++-3.3.3
Date: Mon, 13 Dec 2004 10:39:14 -0800

Hi folks,

The following program:

===========================================

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

struct PODptr
{
   char * ptr;
   size_t sz;
   char * ptr_next_size() const { return (ptr + sz - sizeof(size_t)); }
   char * ptr_next_ptr() const { return (ptr_next_size() - 4); }
   PODptr(char * const nptr, const size_t nsize) : ptr(nptr), sz(nsize) { }
   bool valid() const { return (begin() != 0); }
   char * & begin() { return ptr; }
   char * begin() const { return ptr; }
   size_t & next_size() const { 
     return *(reinterpret_cast<size_t *>(ptr_next_size())); }
   char * & next_ptr() const { 
     return *(reinterpret_cast<char **>(ptr_next_ptr())); }
   PODptr next() const { 
     return PODptr(next_ptr(), next_size()); }
   void next(const PODptr & arg) const { 
     next_ptr() = arg.ptr; next_size() = arg.sz; }
};

void walk_list( PODptr iter )
{
 while (iter.valid())
 {
    const PODptr next = iter.next();
    printf( "saw %08x, next=%08x\n", (int) iter.begin(), (int) next.begin() );
    iter = next;
 }
}

int main( int argc, char * argv[] ) {
  static char buf[100];
  PODptr node(buf, sizeof( buf ));
  node.next(PODptr(0,0));
  walk_list( node );
}

===========================================

crashes when compiled with "g++ -O2".  My specs are:

===========================================

Reading specs from /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/specs
Configured with:
/var/tmp/portage/gcc-3.3.3-r6/work/gcc-3.3.3/configure --prefix=/usr
--bindir=/usr/i686-pc-linux-gnu/gcc-bi\
n/3.3 --includedir=/usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/include
--datadir=/usr/share/gcc-data/i686-pc-linux-gnu/3.3 --ma\
ndir=/usr/share/gcc-data/i686-pc-linux-gnu/3.3/man
--infodir=/usr/share/gcc-data/i686-pc-linux-gnu/3.3/info
--enable-shared \
--host=i686-pc-linux-gnu --target=i686-pc-linux-gnu --with-system-zlib
--enable-languages=c,c++ --enable-threads=posix --ena\
ble-long-long --disable-checking --disable-libunwind-exceptions
--enable-cstdio=stdio --enable-version-specific-runtime-libs\
--with-gxx-include-dir=/usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/include/g++-v3
--with-local-prefix=/usr/local --enable-shar\
ed --enable-nls --without-included-gettext --disable-multilib
--enable-__cxa_atexit --enable-clocale=generic
Thread model: posix
gcc version 3.3.3 20040412 (Gentoo Linux 3.3.3-r6, ssp-3.3.2-2, pie-8.7.6)

===========================================

The assembly language is pretty clearly wrong ... it reads
uninitialized stack slots... here is the output of "g++ -S -O2":

===========================================

walk_list(PODptr):                 //  void walk_list( PODptr iter )
.LFB42:                            //  {
       pushl   %ebp                //
.LCFI0:                            //
       movl    %esp, %ebp          //
.LCFI1:                            //
       pushl   %edi                //
.LCFI2:                            //     PODptr temp;
       leal    -24(%ebp), %edi     //     edi = &temp;
       pushl   %esi                //
.LCFI3:                            //
       pushl   %ebx                //
.LCFI4:                            //
       subl    $44, %esp           //
.LCFI5:                            //
       movl    8(%ebp), %eax       //     eax = iter.ptr;
       movl    12(%ebp), %edx      //     edx = iter.sz;
       movl    %eax, -24(%ebp)     //     temp.ptr = eax;
       movl    %edx, -20(%ebp)     //     temp.sz = edx;
       movl    -24(%ebp), %edx     //     edx = temp.ptr
       testl   %edx, %edx          //     if( !edx )
       je      .L18                //       goto L18;
       movl    -32(%ebp), %ecx     //     PODptr next; ecx =
next.ptr; // garbage
       leal    -32(%ebp), %esi     //     esi = &next;
       movl    -28(%ebp), %ebx     //     ebx = next.sz; // garbage
       .p2align 4,,15              //
.L16:                              //
       movl    %ecx, -32(%ebp)     //     next.ptr = ecx; // garbage
       movl    %edx, %eax          //
       addl    4(%edi), %eax       //
       movl    %ebx, -28(%ebp)     //     next.sz = ebx; // garbage
       movl    -4(%eax), %eax      //     eax = temp.next_size()
       movl    %eax, 4(%esi)       //     next.size = eax
       movl    -32(%ebp), %eax     //     eax = next.ptr // garbage
       movl    %edx, 4(%esp)       //     arg 2: printf( ....., (int)
iter.begin(), ... )
       movl    $.LC0, (%esp)       //     arg 1: printf( "saw %08x
%08x", ..., ... )
       movl    %eax, 8(%esp)       //     arg 3: printf( ..., ...,
(int) iter.next() )
       call    printf              //     printf(...)
       movl    -32(%ebp), %ecx     //     ecx = next.ptr; // garbage
       movl    -28(%ebp), %ebx     //     edx = next.sz; // garbage
       movl    %ecx, -24(%ebp)     //     temp.ptr = ecx;
       movl    -24(%ebp), %edx     //     edx = temp.ptr;
       movl    %ebx, -20(%ebp)     //     temp.sz = edx;
       testl   %edx, %edx          //     if( edx )
       jne     .L16                //       goto L16;
.L18:                              //
       addl    $44, %esp           //
       popl    %ebx                //
       popl    %esi                //
       popl    %edi                //
       popl    %ebp                //
       ret                         //

===========================================

Any help here would be much appreciated.  It's hard to know how to
avoid a bug like this.  (The program is a bit ugly because it's
actually derived from boost::object_pool; I put some effort to boil it
down to a smallish chunk of code).

   -Ken




reply via email to

[Prev in Thread] Current Thread [Next in Thread]