Conversation

Clearly, they cannot actually have one, but the C standard does not allow undefined behavior on infinite recursion. In practice, it's going to overflow the stack, but it's not permitted to optimize it out as LLVM does in some cases due to an implementation bug. It's not allowed.
1
1
It's also not permitted to let the stack overflow go undetected and clobber other things in memory. It's not explicitly required to detect it, but any sane implementation should reliably detect it and abort safely. Clang can't do that outside Windows. It's only safe on Windows.
1
The semantics adopted in C++11 and later for optimization assumptions about infinite loops and the semantics in previous standards don't match C. I don't know the C++ standard well enough to say much about how it works there. I do know how it works in C quite well though.
1
1
It's not permitted to do what LLVM is doing for infinite recursion and LLVM is doing it across all C standards + other languages, because it's a bug, similar to Clang's lack of stack probes outside Windows which is not just a bug but a serious exploitable security vulnerability.
1
LLVM has an optimization bug in the removal of unnecessary calls to pure functions. Infinite recursion is one way to see that bug, but so are infinite loops. C11 does not permit removing the infinite loop `while (1) { ... }`. Consider this example:
1
3
I think this is an interesting bug. It shows that LLVM models 'noreturn' as an effect. If a function never returns and is pure, that means it never halts. LLVM is smart enough not to remove that, as not halting is a side effect, and the standard doesn't permit removing this.
1
1
However, it also shows a bug in LLVM's effects handling. It doesn't have support for the concept of alwaysreturn, only noreturn. It doesn't have the necessary support for performing this optimization, but they choose to do it since they value the optimization over correctness.
1
1
That's why if you remove the if statement, LLVM stops removing the call to the function. It understands that it should not remove a call to a noreturn function. It doesn't understand that functions that aren't detected as noreturn aren't necessarily guaranteed to return though.
1
1