It's usually argued that it would be too hard for the compiler to avoid false positives from templates and macro expansion. I don't like this argument, since distinguishing between "generated" code and "explicit" code isn't that hard. Also, the warning mechanism doesn't need to be perfect to be beneficial: it's generally better to catch some of the security flaws than to catch none. The one tool I've found that does catch many of these errors is "stack": https://github.com/xiw/stack
It operates by identifying "unstable" code. Essentially, it uses Clang to optimize the code twice, once with optimizations on and once with optimizations off. Then it checks to see if any "basic blocks" have been removed. Its main problem is that it's difficult to set up. You have to locally compile a specific older version of LLVM with a particular set of compile flags.
But once you have it up, it catches a lot of non-obvious errors and doesn't have many false positives. Unfortunately, in the sample code I gave above, "stack" doesn't detect any errors, because Clang doesn't doesn't optimize out the "if (string)" statement like GCC does. And it doesn't catch the switch from printf() to puts() because it's a change of which function is called rather than a change in control flow.
It operates by identifying "unstable" code. Essentially, it uses Clang to optimize the code twice, once with optimizations on and once with optimizations off. Then it checks to see if any "basic blocks" have been removed. Its main problem is that it's difficult to set up. You have to locally compile a specific older version of LLVM with a particular set of compile flags.
But once you have it up, it catches a lot of non-obvious errors and doesn't have many false positives. Unfortunately, in the sample code I gave above, "stack" doesn't detect any errors, because Clang doesn't doesn't optimize out the "if (string)" statement like GCC does. And it doesn't catch the switch from printf() to puts() because it's a change of which function is called rather than a change in control flow.