Skip to content

ABI transformations are never applied for variadic arguments #172

klickverbot opened this Issue Sep 29, 2012 · 4 comments

3 participants

LDC 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.

LDC 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
    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))
    add r0, pc
    movt    r2, :upper16:(__D9vastructd6bananaOS9vastructd3foo-(LPC1_1+4))
    ldrd    r0, r1, [r0]
    add r2, pc
    blx _bar
    movs    r0, #0
    pop {r7, pc}
LDC member

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).

LDC 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.


LDC 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
Something went wrong with that request. Please try again.