llvm / llvm/llvm-project

ABI of passing struct with only flexible array member by value disagrees with GCC

Open
#195,572 10 comments 0 reactions 0 assignees View on GitHub
ABI clang:codegen extension:clang extension:gnu
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

Clang compiles this C function:

```c
struct foo {
char member[];
};

long test(struct foo zst, long t, long u, long v, long w, long x, long y,
long z) {
return z;
}
```

To this assembly code on x86-64 Linux ([Godbolt](https://godbolt.org/z/eWKazGxxW)):

```asm
test:
mov rax, qword ptr [rsp + 16]
ret
```

In the LLVM IR, `struct foo zst` is passed by pointer, despite being zero-sized.

In contrast, GCC emits:

```asm
test:
mov rax, qword ptr [rsp + 8]
ret
```

GCC's assembly for this function matches what both GCC and clang emit for this:

```c
struct foo {
char member[0];
};

long test(struct foo zst, long t, long u, long v, long w, long x, long y,
long z) {
return z;
}
```

The same issue exists for `union`s.

This is inconvenient for Rust, where it is [common practice](https://rust-lang.github.io/rust-bindgen/using-fam.html) to map both C flexible array members and C zero-length array members to the same Rust construct (a zero-length Rust array).

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.