On Fri, Sep 15, 2023 at 01:01:23PM +0800, David Gow wrote:
KUnit's deferred action API accepts a void(*)(void *) function pointer which is called when the test is exited. However, we very frequently want to use existing functions which accept a single pointer, but which may not be of type void*. While this is probably dodgy enough to be on the wrong side of the C standard, it's been often used for similar callbacks, and gcc's -Wcast-function-type seems to ignore cases where the only difference is the type of the argument, assuming it's compatible (i.e., they're both pointers to data).
However, clang 16 has introduced -Wcast-function-type-strict, which no longer permits any deviation in function pointer type. This seems to be because it'd break CFI, which validates the type of function calls.
This rather ruins our attempts to cast functions to defer them, and leaves us with a few options:
- Stick our fingers in our ears an ignore the warning. (It's worked so far, but probably isn't the right thing to do.)
- Find some horrible way of casting which fools the compiler into letting us do the cast. (It'd still break CFI, though.)
- Disable the warning, and CFI for this function. This isn't optimal, but may make sense for test-only code. However, I think we'd have to do this for every function called, not just the caller, so maybe it's not practical.
- Manually write wrappers around any such functions. This is ugly (do we really want two copies of each function, one of which has no type info and just forwards to the other). It could get repetitive.
- Generate these wrappers with a macro. That's what this patch does.
I'm broadly okay with any of the options above, though whatever we go with will no doubt require some bikeshedding of details (should these wrappers be public, do we dedupe them, etc).
Thoughts?
Looks awesome :)
We ended up using a wrapper in KMS to workaround this issue and would benefit from it too.
Maxime