Can we keep must progress optimizations around infinite loop in C++ while avoiding some surprising behavior?

The “empty function” thing isn’t really specific to infinite loops; you can trigger it with other forms of undefined behavior. Adding a trap instruction to completely empty functions is a really minor size cost; such functions should be very rare. (I don’t think anyone is really against it, just nobody has proposed a patch.)

Adding a trap instruction after calls which the compiler thinks don’t return (in IR, a “call” followed by an “unreachable”) would be a more significant size cost; calls like that pretty common in some kinds of code. For example, throwing an exception produces code like this. We’d want numbers before we turn this on by default.

For infinite loops specifically, it probably makes sense to adopt the C11 behavior in C++; it would be nice if the C++ committee could officially bless that approach, though.

Compile-time diagnostics for undefined behavior are tricky. It’s hard to detect that a loop is non-trivially infinite from the clang AST. And generally, the feedback we get is that people don’t want diagnostics that depend on compiler optimizations. Such warnings show up inconsistently (so builds break depending on the target/optimization level/etc.). And it’s easy to end up with unfixable false positives (e.g. if some code is unreachable due to jump threading).

4 Likes