[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Optimization bug in g++-3.3.3,
Kenneth Duda <=