Of course I would also prefer a warning, or at least a guarding trap instruction. And maybe compilers should try harder to be friendly in this way.
But they can't be perfect, because the program specified something syntactically valid, but semantically invalid. The module/compiler pass that could theoretically detect it may simply not be issued the necessary information. E.g. a solver may be given the input that a value is in a given range, and from that simplify an operation. If the input is wrong, so is the output.
Reminds me of:
On two occasions I have been asked, 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question.
In the example from the article, though, there could be a pass that simply eliminated dead code. That pass is not a parser of the raw code, so how is it to know that actually, the "dead code" isn't?And a standard that would require dead code elimination to replace not with empty, but with a trap instruction, could go very wrong. You don't want `if (false) { … }` to become `if (false) { trap(); }`. You want it just removed, if a previous pass deemed it dead. Or do you want `int main() { for(;;) {cli_loop();} }` to force adding a trap in the unreachable code after the loop? That's a lot of generated trap instructions.
So in general this means solving the halting problem. Yes, specifically in the post's example, "surely a sufficiently smart compiler could detect something this obvious". Maybe so, but how often is the bug actually this obvious?