[LLVMdev] Wrong calling convention?
Óscar Fuentes
ofv at wanadoo.es
Wed Mar 26 06:39:49 PDT 2008
Hi Duncan.
Duncan Sands <baldrick at free.fr> writes:
>> define internal i1 @Addr_045442A0() {
>> alloca [8 x i8], align 4 ; <[8 x i8]*>:1 [#uses=2]
>> alloca i1, align 4 ; <i1*>:2 [#uses=2]
>> tail call void @F95478DA5_FFI_FN( [8 x i8]* %1 sret )
>
> this call uses the "struct-return" convention (due to the sret attribute).
> On x86 this means that the caller is responsible for adjusting the stack
> pointer after the call for the sret parameter. If the callee is not following
> the sret convention then the stack pointer will be adjusted wrongly and your
> program will die horribly.
>
>> 0x0e8d937b: call 0x5053b0 <_ZN3lp04OpF0IN5IncDB9TDateTimeEXadL_ZNS2_3NowEvEEE1wEv>
>> 0x0e8d9380: sub $0x4,%esp
>
> Here you see the sret stack adjustment.
This looks like the opposite: it is making room for passing a parameter
to the next call (the stack grows downwards).
But you put me on the right track. The problem is that the class is
returned on the stack.
This is the class:
class Foo {
public:
Foo() : data(113.5) {}
static Foo GetFoo() { return Foo(); }
private:
double data;
};
This is the assembler code for Foo::GetFoo:
Dump of assembler code for function _ZN3Foo6GetFooEv:
0x6e08b5a4 <_ZN3Foo6GetFooEv+0>: push %ebp
0x6e08b5a5 <_ZN3Foo6GetFooEv+1>: mov %esp,%ebp
0x6e08b5a7 <_ZN3Foo6GetFooEv+3>: sub $0x14,%esp
0x6e08b5aa <_ZN3Foo6GetFooEv+6>: lea -0x8(%ebp),%eax
0x6e08b5ad <_ZN3Foo6GetFooEv+9>: mov %eax,(%esp)
0x6e08b5b0 <_ZN3Foo6GetFooEv+12>: call 0x6e08b5bc <Foo>
0x6e08b5b5 <_ZN3Foo6GetFooEv+17>: fldl -0x8(%ebp)
0x6e08b5b8 <_ZN3Foo6GetFooEv+20>: leave
0x6e08b5b9 <_ZN3Foo6GetFooEv+21>: ret
End of assembler dump.
I guess that g++ exploits its knowledge of Foo's internals for deciding
how to return the class. But my compiler knows nothing about Foo, so I
must disable this "feature" of g++. Suggestions welcome.
--
Oscar
More information about the llvm-dev
mailing list