It took me forever to track down that there was a bug in my code being triggered by /OPT:ICF
:
Because /OPT:ICF can cause the same address to be assigned to different functions or read-only data members (const variables compiled by using /Gy), it can break a program that depends on unique addresses for functions or read-only data members.
(I had been storing and comparing function pointers for equality, which breaks when the linker throws away identical functions.)
Now I need to find every place where I might have done such a thing.
The test case is of course trivial:
//MSVC: /Gy /link /OPT:ICF
int test1(void) { return 0; }
int test2(void) { return 0; }
int main(void) { return test1 == test2; }
I've tried -Wall
, -Wextra
, -Weverything
, -pedantic
, etc. but none of them generate warnings.
Is there any compiler option or tool (whether part of Visual C++, GCC, Clang, or other) that can analyze my code and tell me where I'm comparing function pointers with each other, like in the code above?
I'm not sure if there exists such a compiler option.
However, there is such a tool. clang-tidy. You can write your own checks for clang-tidy, it's actually remarkably easy if you follow this blog. Specifically, the AST comes with a bunch of matchers already, which should handle the use-case you want.
Something like this seems to work:
Which flags the example in the OP:
That works specifically for the OP case, but you actually have to be more explicit to match all the other likely cases:
Or something close to that effect.