April 24, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #20 from Jacob Carlborg <doob@me.com> 2013-04-23 23:30:49 PDT ---
(In reply to comment #19)

> It doesn't do anything wrong, it just sets EAX to contain the hidden pointer before returning. This is required by the SysV IA-32 ABI but apparently not on OSX.

First, Mac OS X uses a modified version of the SysV IA-32 ABI (there's a link a couple of posts up). Second, If an extern (C) function doesn't behave the same as a C function, in regards to ABI and calling conventions, I would say that the compiler is doing something wrong.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 26, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9931


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@digitalmars.com


--- Comment #21 from Walter Bright <bugzilla@digitalmars.com> 2013-04-25 23:09:41 PDT ---
(In reply to comment #0)
> This code:
> 
> http://pastebin.com/U5XdFfDq

Here's the code from pastebin. I'd prefer small examples to be posted here rather than linked to.
--------------------------------------------
version (D_LP64)
    alias double CGFloat;
else
    alias float CGFloat;

struct NSRect
{
    NSPoint origin;
    NSSize size;
}

public struct NSPoint {
    public CGFloat x;// = 0.0;
    public CGFloat y;// = 0.0;
}

struct NSSize {
    public CGFloat width;// = 0.0;
    public CGFloat height;// = 0.0;
}

alias char* SEL;
alias objc_class* Class;
alias objc_object* id;

struct objc_object
{
    Class isa;
}

struct objc_class;

extern (C)
{
    Class objc_getClass (in char* name);
    id objc_msgSend (id theReceiver, SEL theSelector, ...);
    void objc_msgSend_stret(void* stretAddr, id theReceiver, SEL theSelector,
...);
    SEL sel_registerName (in char* str);
}
extern (C) int printf(in char*, ...);

NSRect foo (id screen)
{
    alias extern (C) NSRect function (id, SEL) frameFp;
    auto fp = cast(frameFp) &objc_msgSend_stret;
    return fp(screen, sel_registerName("visibleFrame".ptr));
}

int main ()
{
    auto cls = objc_getClass("NSScreen".ptr);

    alias extern (C) id function (id, SEL) screenFp;
    auto screen = (cast(screenFp)&objc_msgSend)(cast(id) cls,
sel_registerName("mainScreen".ptr));

    auto frame = foo(screen);

    printf("x=%f y=%f width=%f height=%f\n".ptr, frame.origin.x,
frame.origin.y, frame.size.width, frame.size.height);
    return 0;
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 26, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #22 from Jacob Carlborg <doob@me.com> 2013-04-25 23:35:21 PDT ---
(In reply to comment #21)

> Here's the code from pastebin. I'd prefer small examples to be posted here rather than linked to.

Fair enough. Here's the latest test case. It doesn't depend on any external functions or casts:

C code:

struct Foo
{
    int a;
    int b;
    int c;
};

typedef struct Foo Foo;

Foo foo (int a)
{
    Foo f;
    f.a = 1;
    f.b = 2;
    f.c = 3;
    return f;
}

D code:

struct Foo
{
    int a;
    int b;
    int c;
}

extern (C) Foo foo (int a);

Foo bar ()
{
    return foo(0);
}

extern (C) int printf(in char*, ...);

void main ()
{
    auto frame = bar();
    printf("a=%d b=%d c=%d\n".ptr, frame.a, frame.b, frame.c);
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 26, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #23 from Walter Bright <bugzilla@digitalmars.com> 2013-04-26 00:10:24 PDT ---
https://github.com/D-Programming-Language/dmd/pull/1938

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 26, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #24 from github-bugzilla@puremagic.com 2013-04-26 08:50:36 PDT ---
Commits pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/a2c2ddc1be1890e48ac579a77037fb76bc322572
fix Issue 9931 - Mac OS X ABI not followed when returning structs for extern
(C)

https://github.com/D-Programming-Language/dmd/commit/5167cc1165b7d37c76817ab6c8d353963cf572a8 Merge pull request #1938 from WalterBright/fix9931

fix Issue 9931 - Mac OS X ABI not followed when returning structs for extern
(C)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 26, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #25 from github-bugzilla@puremagic.com 2013-04-26 11:05:39 PDT ---
Commit pushed to dmd-1.x at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/3646e40bc1ebb451c361e4f6c624dd5a1172ef08 Merge pull request #1938 from WalterBright/fix9931

fix Issue 9931 - Mac OS X ABI not followed when returning structs for extern
(C)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 26, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9931


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|REOPENED                    |RESOLVED
         Resolution|                            |FIXED


-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 27, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9931


Jacob Carlborg <doob@me.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|FIXED                       |


--- Comment #26 from Jacob Carlborg <doob@me.com> 2013-04-27 03:56:14 PDT ---
There's still problem with 64bit. It doesn't segfault now but the values of the returned struct is completely wrong. Example:

a=-2077579799 b=32767 c=1517257856

The disassembly for the 64bit C version looks like this (all functions in the
same object file) :

main:
Relocation information (__TEXT,__text) 4 entries
address  pcrel length extern type    scattered symbolnum/value
000000ef True  long   True   BRANCH  False     _printf
000000c2 True  long   True   BRANCH  False     _bar
000000ab True  long   True   SIGNED  False     L_.str
0000005b True  long   True   BRANCH  False     _foo
Relocation information (__LD,__compact_unwind) 3 entries
address  pcrel length extern type    scattered symbolnum/value
00000040 False quad   False  UNSIGND False     1 (__TEXT,__text)
00000020 False quad   False  UNSIGND False     1 (__TEXT,__text)
00000000 False quad   False  UNSIGND False     1 (__TEXT,__text)
(__TEXT,__text) section
_foo:
0000000000000000    pushq    %rbp
0000000000000001    movq    %rsp,%rbp
0000000000000004    movl    %edi,0xec(%rbp)
0000000000000007    movl    $0x00000001,0xe0(%rbp)
000000000000000e    movl    $0x00000002,0xe4(%rbp)
0000000000000015    movl    $0x00000003,0xe8(%rbp)
000000000000001c    movq    0xe0(%rbp),%rax
0000000000000020    movq    %rax,0xf0(%rbp)
0000000000000024    movl    $0x00000003,0xf8(%rbp)
000000000000002b    movl    0xf0(%rbp),%edi
000000000000002e    movl    0xf4(%rbp),%ecx
0000000000000031    movl    0xf8(%rbp),%edx
0000000000000034    movl    %edx,0xd8(%rbp)
0000000000000037    movl    %ecx,0xd4(%rbp)
000000000000003a    movl    %edi,0xd0(%rbp)
000000000000003d    movq    0xd0(%rbp),%rax
0000000000000041    movl    0xd8(%rbp),%edx
0000000000000044    popq    %rbp
0000000000000045    ret
0000000000000046    nopw    %cs:_foo(%rax,%rax)
_bar:
0000000000000050    pushq    %rbp
0000000000000051    movq    %rsp,%rbp
0000000000000054    subq    $0x30,%rsp
0000000000000058    xorl    %edi,%edi
000000000000005a    callq    _foo
000000000000005f    movl    %edx,0xe8(%rbp)
0000000000000062    movq    %rax,0xe0(%rbp)
0000000000000066    movl    0xe0(%rbp),%edx
0000000000000069    movl    0xe4(%rbp),%edi
000000000000006c    movl    0xe8(%rbp),%ecx
000000000000006f    movl    %ecx,0xf8(%rbp)
0000000000000072    movl    %edi,0xf4(%rbp)
0000000000000075    movl    %edx,0xf0(%rbp)
0000000000000078    movl    0xf0(%rbp),%ecx
000000000000007b    movl    0xf4(%rbp),%edx
000000000000007e    movl    0xf8(%rbp),%edi
0000000000000081    movl    %edi,0xd8(%rbp)
0000000000000084    movl    %edx,0xd4(%rbp)
0000000000000087    movl    %ecx,0xd0(%rbp)
000000000000008a    movq    0xd0(%rbp),%rax
000000000000008e    movl    0xd8(%rbp),%edx
0000000000000091    addq    $0x30,%rsp
0000000000000095    popq    %rbp
0000000000000096    ret
0000000000000097    nopw    _foo(%rax,%rax)
_main:
00000000000000a0    pushq    %rbp
00000000000000a1    movq    %rsp,%rbp
00000000000000a4    subq    $0x40,%rsp
00000000000000a8    leaq    L_.str(%rip),%rax
00000000000000af    movl    $_foo,0xfc(%rbp)
00000000000000b6    movl    %edi,0xf8(%rbp)
00000000000000b9    movq    %rsi,0xf0(%rbp)
00000000000000bd    movq    %rax,0xc8(%rbp)
00000000000000c1    callq    _bar
00000000000000c6    movl    %edx,0xd8(%rbp)
00000000000000c9    movq    %rax,0xd0(%rbp)
00000000000000cd    movl    0xd0(%rbp),%edx
00000000000000d0    movl    0xd4(%rbp),%edi
00000000000000d3    movl    0xd8(%rbp),%ecx
00000000000000d6    movl    %ecx,0xe8(%rbp)
00000000000000d9    movl    %edi,0xe4(%rbp)
00000000000000dc    movl    %edx,0xe0(%rbp)
00000000000000df    movl    0xe0(%rbp),%esi
00000000000000e2    movl    0xe4(%rbp),%edx
00000000000000e5    movl    0xe8(%rbp),%ecx
00000000000000e8    movq    0xc8(%rbp),%rdi
00000000000000ec    movb    $_foo,%al
00000000000000ee    callq    _printf
00000000000000f3    movl    $_foo,%ecx
00000000000000f8    movl    %eax,0xc4(%rbp)
00000000000000fb    movl    %ecx,%eax
00000000000000fd    addq    $0x40,%rsp
0000000000000101    popq    %rbp
0000000000000102    ret

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 27, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #27 from Martin Nowak <code@dawg.eu> 2013-04-27 06:48:42 PDT ---
> * If I compile as 64bit everything works fine
> There's still problem with 64bit.

Can you be a little more precise?
Does it fail for the code in comment 22?

> all functions in the same object file

So everything in C or D?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 27, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #28 from Jacob Carlborg <doob@me.com> 2013-04-27 07:15:30 PDT ---
(In reply to comment #27)
> Can you be a little more precise?
> Does it fail for the code in comment 22?

Yes, the code in comment 22.

> So everything in C or D?

The disassembly is in C. Below is the disassembly for the D version of the "bar" function from comment 22:

_D4main3barFZS4main3Foo:
0000000100000b6c        pushq   %rbp
0000000100000b6d        movq    %rsp,%rbp
0000000100000b70        subq    $0x20,%rsp
0000000100000b74        movq    %rdi,0xf8(%rbp)
0000000100000b78        xorl    %esi,%esi
0000000100000b7a        leaq    0xe8(%rbp),%rdi
0000000100000b7e        callq   _foo
0000000100000b83        leaq    0xe8(%rbp),%rsi
0000000100000b87        movq    0xf8(%rbp),%rdi
0000000100000b8b        movsq   (%esi),(%edi)
0000000100000b8d        movsb   (%esi),(%edi)
0000000100000b8e        movsb   (%esi),(%edi)
0000000100000b8f        movsb   (%esi),(%edi)
0000000100000b90        movsb   (%esi),(%edi)
0000000100000b91        movq    0xf8(%rbp),%rax
0000000100000b95        leave
0000000100000b96        ret
0000000100000b97        nopl    0x00(%rax,%rax)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
1 2 3
Next ›   Last »