Bug#153472: G++ 3.1.1 incorrectly handles clobbered registers in "asm volatile ()"
Package: g++-3.1
Version: 1:3.1.1-0pre3
Architecture: i386
G++ 3.1 on i386 seems to handle asm volatile() incorrectly.
Example follows:
t.cpp:
---------------------------------
struct Packet;
struct shm { int receive_count; Packet ** receive; } * rtms_shm;
static inline Packet * receivePacket ( void )
{
static int ind=0;
if ( ind == rtms_shm->receive_count ) return 0;
return rtms_shm->receive[ind++];
}
extern void g ( Packet * );
void h ( void )
{
asm volatile ( "movl $5, %%ebx" : : : "ebx" );
g ( receivePacket() );
}
--------------------------------
It is example only. It was created by cutting a huge source file to the
minimal where the bug is there.
"asm" statement here clobbers %ebx register. And it tells the compiler
after the third semicolon that %ebx is clobbered, so compiler should not
depend on any value stored there.
Constructs like this one are widely used in mixed C++ - ASM programs.
When compiling the example with "g++ -S -O2 -fPIC t.c", the following
code is generated for h() function:
_Z1hv:
.LFB1:
pushl %ebp
.LCFI0:
movl %esp, %ebp
.LCFI1:
pushl %ebx
.LCFI2:
pushl %eax
call .L4
.L4:
popl %ebx
addl $_GLOBAL_OFFSET_TABLE_+[.-.L4], %ebx
#APP
movl $5, %ebx
#NO_APP
movl rtms_shm@GOT(%ebx), %eax
movl (%eax), %eax
movl _ZZ13receivePacketvE3ind@GOTOFF(%ebx), %edx
xorl %ecx, %ecx
cmpl (%eax), %edx
je .L3
movl 4(%eax), %eax
movl (%eax,%edx,4), %ecx
leal 1(%edx), %eax
movl %eax, _ZZ13receivePacketvE3ind@GOTOFF(%ebx)
.L3:
subl $12, %esp
pushl %ecx
.LCFI3:
call _Z1gP6Packet@PLT
addl $16, %esp
movl -4(%ebp), %ebx
leave
ret
In this code, the value of %ebx IS USED in compiled code JUST AFTER the
asm() statement!
It is a definitly a compiler bug that causes mysterious segfaults.
--
To UNSUBSCRIBE, email to debian-gcc-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Reply to: