Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ABI transformations are never applied for variadic arguments #172

Closed
dnadlinger opened this issue Sep 29, 2012 · 4 comments
Closed

ABI transformations are never applied for variadic arguments #172

dnadlinger opened this issue Sep 29, 2012 · 4 comments

Comments

@dnadlinger
Copy link
Member

There is a big problem with the current ABI code: ABI rewrites (such as for turning a struct into an integer so it gets passed in a single register by LLVM) are only ever applied for formal parameters, but not for variadic parameters. This is a problem on x86_64, where there is no difference between variadic and formal paremeters with regard to the calling convention.

The classification scheme needs to happen at least partly at per-call, not per-declaration basis.

For an example of this, see DMD testcase test12.

@smolt
Copy link
Member

smolt commented Apr 9, 2014

Is this the same issue? This is ARM now. I noticed while writing for iOS that structs passed into the variadic part of a extern C function are being passed by ref instead of by value. C library calls end up not working correctly. Below, apple is passed by value, banana is passed by ref.

struct foo
{
    float a;
    float b;
}

extern (C) void bar(foo a, ...);

__gshared foo apple = {1,2};
__gshared foo banana = {3,4};

void main()
{
    bar(apple, banana);
}

results in this thumb2 assembly

    .thumb_func __Dmain
__Dmain:
    push    {r7, lr}
    movw    r0, :lower16:(__D9vastructd5appleOS9vastructd3foo-(LPC1_0+4))
    mov r7, sp
    movt    r0, :upper16:(__D9vastructd5appleOS9vastructd3foo-(LPC1_0+4))
    movw    r2, :lower16:(__D9vastructd6bananaOS9vastructd3foo-(LPC1_1+4))
LPC1_0:
    add r0, pc
    movt    r2, :upper16:(__D9vastructd6bananaOS9vastructd3foo-(LPC1_1+4))
    ldrd    r0, r1, [r0]
LPC1_1:
    add r2, pc
    blx _bar
    movs    r0, #0
    pop {r7, pc}

@dnadlinger
Copy link
Member Author

It certainly sounds like a good guess, though I'm not quite sure what IR parameter attributes the assembly corresponds to. As I don't have an ARM build of LLVM on this machine, I can't easily double-check this right now, but if it's a question of the byval attribute not being set correctly, UnknownTargetABI::passByVal would be the function responsible for that (and I don't think it is taken into consideration for variadic arguments due to this bug).

@smolt
Copy link
Member

smolt commented May 5, 2014

This seems to work for me. I have it in the iOS fork and now structs are passed by value to extern (C) funcs(…). Didn't make any druntime or phobos unit tests fail either.

smolt/ldc@c66fbbe

@kinke
Copy link
Member

kinke commented Feb 25, 2015

Fixed by #768.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants