The following program will fail.
gcc -S -O1 -foptimize-sibling-calls bug.c
bug.c:
============================================
#define stdcall __attribute__((__stdcall__))
struct S {
void (stdcall *f)(struct S *);
int i;
};
void stdcall foo(struct S *s)
{
s->i++;
}
void stdcall bar(struct S *s)
{
foo(s);
s->f(s);
}
int main(void)
{
struct S s = { foo, 0 };
bar(&s);
}
============================================
This is what the compiler produces:
bar:
pushl %ebp
movl %esp, %ebp
pushl %ebx
subl $20, %esp
movl 8(%ebp), %ebx
movl %ebx, (%esp)
call foo
subl $4, %esp
movl %ebx, 8(%ebp)
movl -4(%ebp), %ebx
leave
jmp *(%ebx)
--
Summary: Invalid code produced with -foptimize-sibling-calls
Product: gcc
Version: 4.5.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: d dot g dot gorbachev at gmail dot com
GCC build triplet: i686-pc-linux-gnu
GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40718