At least Rust has left the door open to allow panicking on overflow even in release builds in the future - presumably on platforms where hardware support makes this cheap enough.
The correct (but hard) way to prevent overflow-related bugs would be to insist on the compiler being able to prove that no overflow can occur. Basically the same thing you do in your head to convince yourself that the program is correct and won’t overflow, only in a more formally rigorous fashion. Modulo semantics by itself doesn’t prevent bugs.
Rust has an optional clippy lint that will warn/forbid all basic arithmetic that might over/underflow, forcing you to use dedicated methods with explicit behaviour instead.
It's very annoying , but I use it in code where this is critical.
> And then you may just have introduced side channels in crypto code.
incorrect crypto code. If overflow is intentional, it should be annotated as such in operations, will generate similar assembly and won't panic. If it isn't intentional, then the code was bad to begin with.
If the branch can be mispredicted, and the misprediction happens depending on internal state you don't want to leak (cf. Spectre), then you have a side channel even if the branch is never actually taken.
> (Swift at least traps in release by default -- I wish Rust had chosen to).
I enable it in release on serious projects: