> But the compiler is like "hey! you used the result of this function as an index for this array! i must be in the range [0, 10)! I can use that information!"
As a developer who has seen lots of developers (including himself) make really dumb mistakes, this seems like a very strange statement.
Imagine if you hired a security guard to stand outside your house. One day, he sees you leave the house and forget to lock the door. So he reasons, "Oh, nothing important inside the house today -- guess I can take the day off", and walks off.
That's what a lot of these "I can infer X must be true" reasonings sounds like to me: they assume that developers don't make mistakes; and that all unwanted behavior is exactly the same.
So suppose we have code that does this:
int array[10];
int i = some_function();
/* Lots of stuff */
if ( i > 10 ) {
return -EINVAL;
}
array[i] = newval;
And then someone decides to add some optional debug logging, and forgets that `i` hasn't been sanitized yet:
int array[10];
int i = some_function();
logf("old value: %d\n", array[i]);
/* Lots of stuff */
if ( i > 10 ) {
return -EINVAL;
}
array[i] = newval;
Now
reading `array[i]` if `i` > 10 is certainly UB; but in a lot of cases, it will be harmless; and in the worst case it will crash with a segfault.
But suppose a clever compiler says, "We've accessed array[i], so I can infer that i read into an out-of-bounds write, which has changed worst-case a DoS into a privilege escalation!
I don't know whether anything like this has ever happened, but 1) it's certainly the kind of thing allowed by the spec, 2) it makes C a much more dangerous language to deal with.