Thread overview
[Issue 19841] Wrong ABI for C++ functions taking a struct by value
May 02, 2019
Atila Neves
May 02, 2019
kinke@gmx.net
May 02, 2019
Atila Neves
May 02, 2019
Atila Neves
May 02, 2019
kinke@gmx.net
May 02, 2019
Atila Neves
Aug 29, 2020
Walter Bright
Sep 07, 2020
Walter Bright
Sep 07, 2020
Walter Bright
Sep 07, 2020
Walter Bright
May 02, 2019
https://issues.dlang.org/show_bug.cgi?id=19841

Atila Neves <atila.neves@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |C++, wrong-code

--
May 02, 2019
https://issues.dlang.org/show_bug.cgi?id=19841

kinke@gmx.net changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |kinke@gmx.net

--- Comment #1 from kinke@gmx.net ---
(In reply to Atila Neves from comment #0)
> The equivalent C++ code passes `foo` as an address in RSI.

No it doesn't: https://godbolt.org/z/hyzdMY

--
May 02, 2019
https://issues.dlang.org/show_bug.cgi?id=19841

--- Comment #2 from Atila Neves <atila.neves@gmail.com> ---
Ah. In that case it's the copy ctor that causes this to happen:

https://godbolt.org/z/HZGk6o

--
May 02, 2019
https://issues.dlang.org/show_bug.cgi?id=19841

--- Comment #3 from Atila Neves <atila.neves@gmail.com> ---
It's possible that DIP1018 might change this.

--
May 02, 2019
https://issues.dlang.org/show_bug.cgi?id=19841

--- Comment #4 from kinke@gmx.net ---
(In reply to Atila Neves from comment #2)
> Ah. In that case it's the copy ctor that causes this to happen:

Yes, as it's no POD in C++-terms anymore, affecting the ABI. So in D, you can
define a dummy postblit to make it a non-POD.
IIRC, Microsoft is a lot stricter, and the mere existence of at least one ctor
makes it a non-POD.

--
May 02, 2019
https://issues.dlang.org/show_bug.cgi?id=19841

--- Comment #5 from Atila Neves <atila.neves@gmail.com> ---
A dummy postblit wouldn't work - it wouldn't actually fix up the value. Duplicating the functionality of the C++ copy constructor is undesireable, and using the copy constructor with the latest release candidate of dmd 2.086.0 doesn't work either.

--
August 29, 2020
https://issues.dlang.org/show_bug.cgi?id=19841

Walter Bright <bugzilla@digitalmars.com> changed:

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

--
September 07, 2020
https://issues.dlang.org/show_bug.cgi?id=19841

--- Comment #6 from Walter Bright <bugzilla@digitalmars.com> ---
D's definition of POD is:

1. it is not nested
2. it has no postblits, destructors, or assignment operators
3. it has no ref fields or fields that are themselves non-POD

https://dlang.org/spec/struct.html#POD

C++'s definition is quite a bit more complicated, and changes from one version of the Standard to another:

https://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special/7189821#7189821

For reference, "the equivalent C++ code" is:

struct Foo {
    char _[32];
};

struct Bar {
    Bar(Foo foo);
};

void oops() {
    auto foo = Foo();
    auto bar = Bar(foo);
}

--
September 07, 2020
https://issues.dlang.org/show_bug.cgi?id=19841

--- Comment #7 from Walter Bright <bugzilla@digitalmars.com> ---
Compiling the D version on Linux64 gives:

_D5test84oopsFZv:
                push    RBP
                mov     RBP,RSP
                sub     RSP,030h
                lea     RAX,-028h[RBP]
                xor     ECX,ECX
                mov     [RAX],RCX
                mov     8[RAX],RCX
                mov     010h[RAX],RCX
                mov     018h[RAX],RCX
                mov     -8[RBP],CL
                push    dword ptr -010h[RBP]
                push    dword ptr -018h[RBP]
                push    dword ptr -020h[RBP]
                push    dword ptr -028h[RBP]
                lea     RDI,-8[RBP]
                call      _ZN3BarC1E3Foo@PC32
                add     RSP,020h
                mov     RSP,RBP
                pop     RBP
                ret

which looks equivalent to the C++ code generated by kinke's godbolt example:

        push    rbp
        mov     rbp, rsp
        sub     rsp, 48
        mov     QWORD PTR [rbp-32], 0
        mov     QWORD PTR [rbp-24], 0
        mov     QWORD PTR [rbp-16], 0
        mov     QWORD PTR [rbp-8], 0
        lea     rax, [rbp-33]
        push    QWORD PTR [rbp-8]
        push    QWORD PTR [rbp-16]
        push    QWORD PTR [rbp-24]
        push    QWORD PTR [rbp-32]
        mov     rdi, rax
        call    Bar::Bar(Foo)
        add     rsp, 32
        nop
        leave
        ret

So I'm going to mark this as worksforme.

--
September 07, 2020
https://issues.dlang.org/show_bug.cgi?id=19841

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |WORKSFORME

--