This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
x86 64 bit function argument bug?
- From: Stephen Biggs <xyzzy at hotpop dot com>
- To: GCC list <gcc at gcc dot gnu dot org>
- Date: 04 May 2003 15:35:46 -0200
- Subject: x86 64 bit function argument bug?
The following weird 2 lines of C code (yes, I know taking the address of
a disappearing entity is an evil thing!):
int *i ( int arg ) { return &arg; }
long long *ll ( long long arg ) { return &arg; }
... compile on the x86 into:
.file "test.c"
.text
.align 2
.p2align 2,,3
.globl i
.type i,@function
i:
pushl %ebp
movl %esp, %ebp
leal 8(%ebp), %eax
leave
ret
.Lfe1:
.size i,.Lfe1-i
.align 2
.p2align 2,,3
.globl ll
.type ll,@function
ll:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
leal -8(%ebp), %eax
leave
ret
.Lfe2:
.size ll,.Lfe2-ll
.ident "GCC: (GNU) 3.2 20020903 (Red Hat Linux 8.0 3.2-7)"
Note that this works as expected (that is, as with the integer argument)
with every other type except the "long long" as above and "double" which
are both 64 bit types on the x86.
Is this a bug or simply luck that the integer type works and the long
long doesn't? This is compiled with -O3 optimization. With -O0, the
"long long" code goes through all sorts of gymnastics storing the
argument back into the place where it originally was on the stack before
taking the address of the wrong place:
.align 2
.globl ll
.type ll,@function
ll:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
movl 8(%ebp), %eax
movl 12(%ebp), %edx
movl %eax, -8(%ebp)
movl %edx, -4(%ebp)
leal -8(%ebp), %eax
leave
ret
.Lfe2:
.size ll,.Lfe2-ll
Note that the 2.4 Linux kernel depends on this compiling as it expects
in at least one place that I know of:
net/core/neighbour.c
void neigh_destroy(struct neighbour *neigh)
{
struct hh_cache *hh;
if (!neigh->dead) {
printk("Destroying alive neighbour %p from %08lx\n",
neigh,
*(((unsigned long*)&neigh)-1));
return;
}
If this is a bug, then is it fixed in a later revision of GCC, and if
so, can anybody point me to the place so I can regress it into 3.2?
If it is not a bug and is expected behavior, can anybody think of any
sort of fairly portable work around?
Thanks.