Clang and GCC already consider that broken per the standard. It was also very explicitly made to be broken in C++ already, which tends to trickle back to the C standard since it's a lot of the same people making the decisions and they reference each other as justifications.
Conversation
open-std.org/jtc1/sc22/wg14 appears to be a more recent draft of what I linked earlier by the way. We'll see how they end up deciding to clarify it for C2X. My feeling is they will bend over backwards to permit / attempt to formalize existing real world compiler interpretations.
1
I'm not arguing that what Clang and GCC currently do is correct, but I am saying that they currently do it, and that it's likely to become officially correct *because* they want to it. Type-based alias analysis is similar. They tried to allow it, and will readjust it as needed.
1
1
Type-based alias analysis is possible to specify consistently, and has clear reasons you want to do it. This provenance stuff has absolutely no motivation, because deriving pointers from ints/reprs is rare, and when you do it, you actually mean it.
2
1
All the special cases they talk about in the draft are ill-defined and impossible to specify formally in a consistent manner. The people trying to do this have no idea what they're doing and it shows.
1
That's true for a lot of the standard process including how they defined TBAA. Their decision that all side effect free loops can be assumed to terminate (unless the condition is a constant) is pretty messed up and Clang uses that to justify the issue I mentioned earlier.
1
1
Here is my usual test case for Clang:
gist.github.com/thestinger/139
Compile this with -O0 and it will infinite loop as it should. Compile it with -O2 and it won't. They've done this since long before standard allowed infinite loops to terminate and it doesn't allow this even now.
1
Removing the conditional return bypasses the issue because it makes the function get marked as noreturn which is treated as an effect. However, there is no concept of a function that may not return, and they assume that all non-noreturn functions will return to let them do it.
2
That's just how they do things. They are determined to do the optimization (removing calls to pure functions) and will do it, even before they have a way to do the optimization correctly. They will get the standard changed to permit things like it as needed too, when they aren't.
2
The C11 infinite loop termination thing resulted in fixing this issue becoming an extremely low priority. It's a major problem for other languages built on LLVM with safe semantics too. It also applies to an infinite loop via recursion including via a guaranteed tail call.

