Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any way to generate warnings for function-pointer comparisons?

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?

like image 335
user541686 Avatar asked Jan 29 '18 05:01

user541686


People also ask

Can we compare function pointer?

Two function pointers can be compared with the == and != operators, just like any other kind of pointers. We can also compare a function pointer to the NULL pointer using the == and != operators.

Are function pointers safe?

Pointers to member functions in C++ This is how C++ uses function pointers when dealing with member functions of classes or structs. These are invoked using an object pointer or a this call. They are type safe in that you can only call members of that class (or derivatives) using a pointer of that type.

Can we increment function pointer?

When a pointer is incremented, it actually increments by the number equal to the size of the data type for which it is a pointer. For Example: If an integer pointer that stores address 1000 is incremented, then it will increment by 2(size of an int) and the new address it will points to 1002.

What is type safe function pointer?

A delegate is a type-safe function pointer that can reference a method that has the same signature as that of the delegate. You can take advantage of delegates in C# to implement events and call-back methods. A multicast delegate is one that can point to one or more methods that have identical signatures.


1 Answers

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:

binaryOperator(     anyOf(hasOperatorName("=="), hasOperatorName("!=")),     hasLHS(ignoringImpCasts(declRefExpr(hasType(functionType())))),     hasRHS(ignoringImpCasts(declRefExpr(hasType(functionType()))))) 

Which flags the example in the OP:

fp.cxx:3:25: note: "root" binds here int main(void) { return test1 == test2; }                         ^~~~~~~~~~~~~~ 

That works specifically for the OP case, but you actually have to be more explicit to match all the other likely cases:

const auto AnyFunc = ignoringImpCasts(declRefExpr(hasType(anyOf(     functionType(),     pointsTo(functionType()),     references(functionType())))));  Finder->AddMatcher(binaryOperator(     anyOf(hasOperatorName("=="), hasOperatorName("!=")),     hasLHS(AnyFunc),     hasRHS(AnyFunc)).bind("op"), this); 

Or something close to that effect.

like image 178
Barry Avatar answered Sep 22 '22 09:09

Barry