llvm / llvm/llvm-project

Clang generates invalid code (crash) for template pack expansion when using `-nostdlib` and `-O0`

Open
#183,881 0 comments 0 reactions 0 assignees View on GitHub
clang
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

Minimal example for Linux:
```c
struct typ {
long a;
long b;
};

struct typ2 {
long a;
long b;
};

auto func(typ s) -> void {
}

template
auto unpack(A... args) -> typ2 {
(func(args), ...);
return {};
}

extern "C" auto _start() -> void {
typ var = { 4 , 4 };
typ2 r = unpack(var);

register long ret asm("rax") = 60;
register long r0 asm("rdi") = 0;

__asm__ volatile(
"syscall"
: "+r"(ret)
: "r"(r0)
: "rcx", "r11", "memory");
}
```
Compile with `-nostdlib -e _start`. The program terminates with SIGSEGV at the parameter pack expansion (according to gdb). Checked trunk on godbolt and the results are the same.

The problem disappears with any of these conditions:
- Using anything other than `-O0`
- `typ` fits into one register (two `int`s max on my machine)
- `typ2` fits into one register
- `typ2` is big enough for a `memset` optimization to kick in (more than two `long`s on my machine)
- `unpack()` returns void
- Not using `-nostdlib` and doing a normal `int main` with `return 0`

My machine: `Linux kde 6.18.9-zen1-2-zen`

Contributor guide

Open the contributing guide

Research direction

Start with the minimal C++ reproducer in the issue and compile it with Clang using -nostdlib, -e _start, and -O0. Use gdb to confirm the SIGSEGV at the parameter-pack expansion, then compare the listed conditions; done means the exact reproducer no longer crashes while the contrasting cases remain valid.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, linux
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.