Issue 144164
Summary Clang on macOS does not emit stack-passed arguments when calling __attribute__((ms_abi)) functions from System V callers
Labels clang
Assignees
Reporter Inakito
    Description:

When compiling with Apple Clang 17.0.0 on macOS, calls from System V ABI functions (e.g., main) to functions marked with __attribute__((ms_abi)) do not correctly follow the Microsoft x64 ABI. Specifically, arguments that exceed the first four (passed in RCX, RDX, R8, R9) are not passed at all — they are not placed on the stack as required.

This causes serious runtime issues in ms_abi variadic functions which expect those parameters.

Environment:

- macOS 14.x (Apple Silicon or Intel, both reproducible)
- Apple Clang 17.0.0 (Xcode 15.3)
- Target: x86_64 (System V by default)
- Tested with -O0 and -O1

Reproduction Case:

```c
#include <stdio.h>

__attribute__((ms_abi)) void systemv_printf(const char *fmt, ...);

int main() {
    double f1 = 1.1, f2 = 2.2, f3 = 3.3, f4 = 4.4, f5 = 5.5;

    // Only the first 4 arguments are passed
    systemv_printf("%g %g %g %g %g\n", f1, f2, f3, f4, f5);
    return 0;
}
```

Implementation of systemv_printf attempts to read the 5th argument from the stack using frame pointer offset — but it's missing.

Expected behavior:

According to the Microsoft x64 ABI specification:
- First four arguments → in RCX, RDX, R8, R9
- Floating-point args duplicated into XMM0–XMM3
- Additional arguments → placed on the stack, 8-byte aligned
- Callee uses va_start or manual stack access to retrieve extra args

Actual behavior:

Clang emits code for the ms_abi call with only the first 4 arguments passed in registers. The 5th and beyond are not passed at all — no stack space is used, and the values are never pushed or stored.

Disassembly confirms this — even with volatile variables and -O0:

```asm
; systemv_printf("%g %g %g %g %g\n", f1, f2, f3, f4, f5);

leaq   ... -> %rcx    ; format string
movq   ... -> %rdx    ; f1
movq   ... -> %r8     ; f2
movq   ... -> %r9     ; f3
; NO instruction for f4 or f5 (e.g. mov to [rsp + N])
callq  systemv_printf
```

Control Test (ms_abi → ms_abi):

When both caller and callee are marked __attribute__((ms_abi)), all arguments including the 5th float are properly passed — the last argument is correctly copied to [rsp+0x20] and accessible.

This suggests that Clang fails to emit proper Microsoft ABI code only when the caller is System V.

Impact:

This breaks interoperability between System V code (the default on macOS) and ms_abi functions — especially for printf-like variadic trampolines or ABI bridging layers, which depend on full argument delivery.

Suggested Fix:

Ensure that when a System V function calls an __attribute__((ms_abi)) function:
- The Microsoft ABI rules are fully applied
- Additional arguments beyond the 4th are pushed on the stack

Thank you!

Let me know if you'd like a full reproducer or test case archive.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to