GCC 2.97 miscompiles with -fomit-frame-pointer

Andreas Franck afranck@gmx.de
Thu Dec 28 04:15:00 GMT 2000


Hello together,

When compiling the following code with -O2 -fomit-frame-pointer, GCC
miscompiles the main function: the local stack space is cleared
before func2 is called, thus overwriting the local tmp structure with
its address and the return address. Compiling without
-fomit-frame-pointer leaves everything fine and working.

This only happens in this certain assembler situation, which I
reproduced from a very similar structure in linux-2.4.0-test12, which
therefore fails on booting when compiled with recent GCC snapshots.

GCC 2.95.2 compiles this fine, regardless of -fomit-frame-pointer.

I think it is unwise to assume a structure is no longer needed when
a pointer to it is passed to an assembler routine not explicitly
mentioning one of its members, so this should be fixed IMHO.

I have submitted a full bug report through gccbug.

Compile and run the following code with and without
-fomit-frame-pointer on any Intel x86 platform:

struct mystruct {
        int member1;
        int member2;
};
 
void func1(struct mystruct* s)
{
        s->member1 = 1;
        s->member2 = 2;
}
 
void inline func2(struct mystruct* s)
{
        __asm__ __volatile__(
                "decl (%0)\n\t"         /* decrement member1 */
                "call func3\n\t"
                :/* no outputs */
                :"c" (s)                /* Base address of the structure */
                :"memory");             /* This asm modifies memory */
}
 
asm(
".align 4\n"
".globl func3\n"
"func3:\n\t"
        "pushl %ecx\n\t"        /* Push structure address as parameter */
        "call func4\n\t"
        "popl %ecx\n\t"         /* And get it back.. */
        "ret"
);
 
void func4(struct mystruct* s)
{
        if (s->member1)
                abort();
}
 
int main(void)
{
        struct mystruct tmp;
 
        func1(&tmp);
        func2(&tmp);
 
        return 0;                                                             
}

A possible fix would be to change  the assembler code in func2 to:
 
        __asm__ __volatile__(
                "decl %1\n\t"
                "call func3\n\t"
                :"=m" (s->member1)
                :"m" (s->member1), "c" (s)
                :"memory"); 


-- 
->>>----------------------- Andreas Franck --------<<<-
---<<<---- Andreas.Franck@post.rwth-aachen.de --->>>---
->>>---- Keep smiling! ----------------------------<<<-


More information about the Gcc-bugs mailing list