Thread overview
[Issue 22960] importC: K&R-style functions assume variadic calling convention
Mar 30, 2022
Walter Bright
Mar 30, 2022
Iain Buclaw
Mar 30, 2022
Iain Buclaw
Mar 30, 2022
duser@neet.fi
Dec 17, 2022
Iain Buclaw
Apr 14, 2023
Walter Bright
Apr 15, 2023
Dlang Bot
Apr 19, 2023
Dlang Bot
March 30, 2022
https://issues.dlang.org/show_bug.cgi?id=22960

Walter Bright <bugzilla@digitalmars.com> changed:

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

--- Comment #1 from Walter Bright <bugzilla@digitalmars.com> ---
I don't really understand this.

    int printf();

is variadic. All K+R functions are variadic.

--
March 30, 2022
https://issues.dlang.org/show_bug.cgi?id=22960

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ibuclaw@gdcproject.org

--- Comment #2 from Iain Buclaw <ibuclaw@gdcproject.org> ---
(In reply to Walter Bright from comment #1)
> I don't really understand this.
> 
>     int printf();
> 
> is variadic. All K+R functions are variadic.
I guess the difference is whether the body of `other` has code generated as-if it is variadic.

Yes, variadic in the sense of "we accept any number of arguments to be called to us".  But not variadic in that those extraneous arguments are ever read by the callee.

--
March 30, 2022
https://issues.dlang.org/show_bug.cgi?id=22960

--- Comment #3 from Iain Buclaw <ibuclaw@gdcproject.org> ---
DMD's undoing here is that it set's up a va_list in the prologue, but k&r functions are pseudo-variadic, so it can get away without having va_list.

In fact, it's an error to construct a va_list object in a k&r function in gcc:
---
void other(x)
        int x;
{
  __builtin_va_list argp;
  __builtin_va_start(argp, x);
}
// file2.c: In function ‘other’:
// file2.c:5:3: error: ‘va_start’ used in function with fixed arguments
---

--
March 30, 2022
https://issues.dlang.org/show_bug.cgi?id=22960

--- Comment #4 from duser@neet.fi ---
i thought this might be hard to explain

the issue is that all K&R functions have this in the body:

% dmd -c -vasm file2.c
other:
0000:   55                       push      RBP
0001:   48 8B EC                 mov       RBP,RSP
0004:   48 81 EC D0 00 00 00     sub       RSP,0D0h
000b:   48 89 B5 38 FF FF FF     mov       -0C8h[RBP],RSI
0012:   48 89 95 40 FF FF FF     mov       -0C0h[RBP],RDX
0019:   48 89 8D 48 FF FF FF     mov       -0B8h[RBP],RCX
0020:   4C 89 85 50 FF FF FF     mov       -0B0h[RBP],R8
0027:   4C 89 8D 58 FF FF FF     mov       -0A8h[RBP],R9
002e:   0F B6 C0                 movzx     EAX,AL
0031:   C1 E0 02                 shl       EAX,2
0034:   4C 8D 1D 2A 00 00 00     lea       R11,[02Ah][RIP]
003b:   49 29 C3                 sub       R11,RAX
003e:   48 8D 45 DF              lea       RAX,-021h[RBP]
0042:   41 FF E3                 jmp       R11D
0045:   0F 29 78 F1              movaps    -0Fh[RAX],XMM7
0049:   0F 29 70 E1              movaps    -01Fh[RAX],XMM6
004d:   0F 29 68 D1              movaps    -02Fh[RAX],XMM5
0051:   0F 29 60 C1              movaps    -03Fh[RAX],XMM4
0055:   0F 29 58 B1              movaps    -04Fh[RAX],XMM3
0059:   0F 29 50 A1              movaps    -05Fh[RAX],XMM2
005d:   0F 29 48 91              movaps    -06Fh[RAX],XMM1
0061:   0F 29 40 81              movaps    -07Fh[RAX],XMM0
0065:   C7 40 01 08 00 00 00     mov       dword ptr 1[RAX],8
006c:   C7 40 05 30 00 00 00     mov       dword ptr 5[RAX],030h
0073:   4C 8D 5D 10              lea       R11,010h[RBP]
0077:   4C 89 58 09              mov       9[RAX],R11
007b:   48 2D AF 00 00 00        sub       EAX,0AFh
0081:   48 89 80 C0 00 00 00     mov       0C0h[RAX],RAX
0088:   C9                       leave
0089:   C3                       ret

the jump there depends on the value of AL and will malfunction if it has a value other than 0-8

K&R functions are interchangeable with normal ones in gcc and clang, but not in dmd because of the dependence on AL/RAX being set to a valid value before calling (as is done when calling a variadic function)

some libraries like zlib (and its bindings in phobos) depend on K&R functions being callable the same way as normal ones

gcc/clang don't emit the code to save registers in K&R functions, and if va_start/etc can't be used inside one then there's no reason to

--
December 17, 2022
https://issues.dlang.org/show_bug.cgi?id=22960

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P1                          |P3

--
April 14, 2023
https://issues.dlang.org/show_bug.cgi?id=22960

--- Comment #5 from Walter Bright <bugzilla@digitalmars.com> ---
Consider:
--------------
int abc();
int def(const char *, ...);
int ghi(const char *, int i);

int main()
{
    abc("hello world %d\n", 1);
    def("hello world %d\n", 2);
    ghi("hello world %d\n", 3);
    return 0;
}
-------------
Compiled with gcc:
-------------
main:
                push    RBP
                mov     RBP,RSP
                mov     ESI,1
                mov     EDI,offset FLAT:.rodata@32
                mov     EAX,0
                call      abc@PC32
                mov     ESI,2
                mov     EDI,offset FLAT:.rodata@32
                mov     EAX,0
                call      def@PC32
                mov     ESI,3
                // look ma, no mov EAX,0 !!
                mov     EDI,offset FLAT:.rodata@32
                call      ghi@PC32
                mov     EAX,0
                pop     RBP
                ret
--------
The code generated for calls to abc() and def() is the same, it is ghi() that
is different.

--
April 15, 2023
https://issues.dlang.org/show_bug.cgi?id=22960

Dlang Bot <dlang-bot@dlang.rocks> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull

--- Comment #6 from Dlang Bot <dlang-bot@dlang.rocks> ---
@WalterBright created dlang/dmd pull request #15107 "fix Issue 22960 - importC: K&R-style functions assume variadic callin…" fixing this issue:

- fix Issue 22960 - importC: K&R-style functions assume variadic calling convention

https://github.com/dlang/dmd/pull/15107

--
April 19, 2023
https://issues.dlang.org/show_bug.cgi?id=22960

Dlang Bot <dlang-bot@dlang.rocks> changed:

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

--- Comment #7 from Dlang Bot <dlang-bot@dlang.rocks> ---
dlang/dmd pull request #15107 "fix Issue 22960 - importC: K&R-style functions assume variadic callin…" was merged into master:

- cf3fe2d4c73541332cea045509c89e47532a9cb3 by Walter Bright:
  fix Issue 22960 - importC: K&R-style functions assume variadic calling
convention

https://github.com/dlang/dmd/pull/15107

--