Actually I would argue the opposite.
There are a number of cases where behaviour is undefined by the C standard but where it is obvious what would happen with a “dumb compiler” on a given platform. Cases like allowing a signed integer to overflow or accessing the same memory though variables of two different types.
Recent versions of gcc (and clang) have started treating these cases as optimisation opportunities not caring if they change how the binary behaves in the “undefined behaviour” condition. This is very bad if your codebase was written by people who treated C like a “portable assembler”. As time went on the optimisers have started looking at larger and larger chunks of code when doing these optimisations increasing the chance the binary will end up doing something other than “what a binary built by a dumb compiler” would do.
There are compiler switches to restore “traditional” behaviour (-fwrapv and -fno-strict-aliasing for the two I mentioned above) , but first you have to know about them.
While in principle a compiler bug could turn compliant code into a security hole I would consider the risk of this to be negligable in the grand scheme of things.