For an array, the length may change but it's not infinite, so the loop always terminates. It would be better to evaluate the length only once before the loop, though, if you know it won't change but the compiler can't know that.
Conversation
It depends on the simplicity of a condition and how it's written. You could write a binary search so that the compiler can see that it always terminates, but it wouldn't be the normal way to write it, etc. Many loops are not going to be verifiable as trivially terminating.
1
Mutually recursive function calls are another case that's very difficult. In order to avoid treating every single function call as needing to have that universal side effect inserted (destroying tons of optimization), the compiler would have to analyze the call graph.
1
Even if the recursion isn't via guaranteed tail calls stack overflow is well-defined and safe in these languages. It CANNOT be replaced with arbitrary memory corruption. They're saying that even remotely safe languages should have significantly worse compile-time and performance.
2
It's unreasonable, especially since the optimization they're performing is still wrong with this feature available. So sure, they can decide to needlessly hurt safe languages, but their implementation is still wrong and unsafe. It's wrong for C and C++ too.
1
C compilers should be guaranteeing that stack overflow is safe and guaranteed to trap too. They shouldn't be optimizing out infinite recursion as they will happily do. It should either infinite loop or crash to be correct, not fall through to other code in an indeterminate state.
1
Guaranteed-to-trap isn't really safe unless you just count process termination is safe. In the presence of optimizations, there's no good way to assess what changes to state have or haven't taken place yet at the point of trap, so you can't really continue execution.
1
I'm saying that it should be guaranteed to trap and lead to the process being killed. That's perfectly safe. It's always a bug and could be exploited for denial of service but it remains memory and type safe. It can't be exploited for arbitrary code execution.
2
1
OK. That's pretty reasonable (though not what I'd call safe) and should be satisfied on modern compilers with
-fstack-clash-protection assuming you have guard pages.
1
Yeah, but even if Clang had -fstack-clash-protection (it doesn't yet), it will happily optimize based on the *assumption* that infinite recursion doesn't happen, so it will remove the possibility of a stack overflow guaranteed to safely terminate the process, and allow worse.
2
It probably sounds weird to care so much about this, but it actually comes up. It's an insignificant issue for C and C++ where there are so many other safety issues. In Rust, you are often forced to prove you handled something exhaustively, and this blows a major hole in it. etc.
Absolutely; I don't doubt you there. But I think there are mitigations that the Rust frontend could make, at the cost of optimizations, unless/until LLVM fixes its rotten core.
The bug was rediscovered over and over many times by people using Rust because they would write something to prove to the compiler that the case is handled (perhaps via an infinite loop never reached in practice - if the code isn't buggy - but their code is buggy and hits it).

