llvm / llvm/llvm-project

UB in a function fails to stop control flow w/in the function after LLVM 12 (no trapping)

Open
#174,844 12 comments 0 reactions 0 assignees View on GitHub
clang:codegen undefined behaviour
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

In a function w/ undefined behavior, a `nullptr` deref in this case, its possible for control to flow off into the ether. Looking back, it seems like we used to insert `llvm.trap` back in LLVM 12, but stopped in LLVM 13.

Minimal Example: https://godbolt.org/z/63q8j3r74

Stripped down test case: https://godbolt.org/z/r5vx4Gcs3

I discovered this when some test code started failing after a Toolchain update. It seems we were just previously lucky about code layout in the library, and indeed the test code (from an [io_uring test](https://github.com/axboe/liburing/blob/master/test/coredump.c)) was previously falling off the end and luckily triggering a SIGSEGV. After the toolchain update, that didn't happen and it caused an OOM.

Minimal example:
```cpp
#include

static void test(void) {
int *ptr = NULL;
*ptr = 0;
exit(0);
}

void foo() { test(); }
```

LLVM 12
```llvm
define internal fastcc void @test()() unnamed_addr {
entry:
call void @llvm.trap()
unreachable
}
```

```asm
foo():
ud2
```

LLVM 13+:
```llvm
define internal fastcc void @test()() unnamed_addr {
entry:
unreachable
}
```

```asm
foo():
```

As you can see (and is more clearly illustrated in the pass pipeline in the linked godbolt examples) we used to emit a trap instruction, but that no longer happens in GlobalOpt for some reason.

The test itself isn't particularly important to us, and I know UB has all kinds of discussion and nassal demons etc, but I really don't think its great for execution to just run off into the binary over just trapping. I'd would have thought that in this case we'd at most remove the call to `exit()` and the `store`, but that we'd still have a return (or trap). Can we restore the previous behavior? Was this an intentional change? Are there options to control this that I'm unaware of?

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.