I recently read something discussing common threading pitfalls and code similar to yours came up.
It is kind of amazing how many non-intuitive optimizations can be made on code like that.
For example, it might be rewritten to something like:
initialize a
do stuff
use a
if (!foo)
undo using a
or rewritten into two function blocks, one for if (foo) and one for if (!foo).
or the initialization of a might be moved down into the other if (foo) block.
So anyway, it is entirely possible that after GCC swizzles the code around it cannot tell anymore. It might have actually used a without even looking at foo, intending to undo it later.