https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105729
Bug ID: 105729 Summary: False positive UBsan "reference binding to null pointer of type" when evaluating array indexing which throws exception Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: other Assignee: unassigned at gcc dot gnu.org Reporter: egor_suvorov at mail dot ru Target Milestone: --- Consider the following code: int range_check(int x) { throw 0; } struct Bar {}; struct Foo { Bar *data = nullptr; const Bar &get(int x) const { return data[range_check(x)]; } }; int main() { Foo b; try { b.get(-1); } catch (...) { } } In my understanding, it contains no UB: although binding a reference to `data[range_check(x)]` would result in UB due to a null pointer reference (or an invalid pointer altogether), it is never evaluated as `range_check` just throws an exception. Hence, this program should not trigger any UBsan (undefined sanitizer) warnings. I was able to reproduce it on Ubuntu 20.04 with both "g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0" and "gcc version 10.3.0 (Ubuntu 10.3.0-1ubuntu1~20.04)": 1. Compile the code from above with `g++ -fsanitize=undefined a.cpp` 2. Run `./a.out` 3. Expected output: empty. Real output: a.cpp:8:23: runtime error: reference binding to null pointer of type 'const struct Bar' This also reproduces on the trunk version of GCC at the Compiler Explorer (https://godbolt.org/z/q5edxMbaE), but I was unable to find Clang version with such behavior. Additional information: * If you set a `catch throw` in GDB in the program above, you get stopped inside `__cxa_throw` after the `reference binding to null pointer` message is emitted by the sanitizer. So it looks like the check is performed before actually running the `range_check` function, which is a good idea unless exceptions are involved. * Moving the field to a local/global variable hides the issue * Removing const-qualification from the method hides the issue