For the compiler to do the optimization, it must be sure that regardless of how bar is implemented, and how foo is called, well-defined behavior will not change.
Since the implementation of bar and the call to foo are unknown to the compiler, when it compiles foo, the theoretical existence of such a case is enough to prevent the optimization, even if it doesn't happen in reality.
Here's an example for such a situation. The important points are:
1. The parameter p points to write-only memory (e.g. memory mapped I/O).
2. bar is unsafe for use with a write-only pointer (maybe it writes it and then reads it back, expecting the same value).
The function foo is safe for use with a write-only pointer, because it only writes p. This is true even if bar is unsafe, because bar never gets p. With the suggested optiomization, bar does get p, which may cause trouble.
Here's an example for the file containing bar and the call to foo.
static int increment;
void bar(int *restrict p) {
(*p)=0;
if (increment) (*p)++;
}
void foo(int *restrict p);
int main(int ac, char **av) {
int *p = get_io_addr(); /* Get a write-only memory mapped I/O address */
increment = atoi(av[1]);
foo(p);
return 0;
}