This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Add a warning for invalid function casts


Ping...

for the latest version of my patch which can be found here:

https://gcc.gnu.org/ml/gcc-patches/2017-10/msg00559.html


Thanks
Bernd.

On 10/10/17 00:30, Bernd Edlinger wrote:
> On 10/09/17 20:34, Martin Sebor wrote:
>> On 10/09/2017 11:50 AM, Bernd Edlinger wrote:
>>> On 10/09/17 18:44, Martin Sebor wrote:
>>>> On 10/07/2017 10:48 AM, Bernd Edlinger wrote:
>>>>> Hi!
>>>>>
>>>>> I think I have now something useful, it has a few more heuristics
>>>>> added, to reduce the number of false-positives so that it
>>>>> is able to find real bugs, for instance in openssl it triggers
>>>>> at a function cast which has already a TODO on it.
>>>>>
>>>>> The heuristics are:
>>>>> - handle void (*)(void) as a wild-card function type.
>>>>> - ignore volatile, const qualifiers on parameters/return.
>>>>> - handle any pointers as equivalent.
>>>>> - handle integral types, enums, and booleans of same precision
>>>>>     and signedness as equivalent.
>>>>> - stop parameter validation at the first "...".
>>>>
>>>> These sound quite reasonable to me.  I have a reservation about
>>>> just one of them, and some comments about other aspects of the
>>>> warning.  Sorry if this seems like a lot.  I'm hoping you'll
>>>> find the feedback constructive.
>>>>
>>>> I don't think using void(*)(void) to suppress the warning is
>>>> a robust solution because it's not safe to call a function that
>>>> takes arguments through such a pointer (especially not if one
>>>> or more of the arguments is a pointer).  Depending on the ABI,
>>>> calling a function that expects arguments with none could also
>>>> mess up the stack as the callee may pop arguments that were
>>>> never passed to it.
>>>>
>>>
>>> This is of course only a heuristic, and if there is no warning
>>> that does not mean any guarantee that there can't be a problem
>>> at runtime.  The heuristic is only meant to separate the
>>> bad from the very bad type-cast.  In my personal opinion there
>>> is not a single good type cast.
>>
>> I agree.  Since the warning uses one kind of a cast as an escape
>> mechanism from the checking it should be one whose result can
>> the most likely be used to call the function without undefined
>> behavior.
>>
>> Since it's possible to call any function through a pointer to
>> a function with no arguments (simply by providing arguments of
>> matching types) it's a reasonable candidate.
>>
>> On the other hand, since it is not safe to call an arbitrary
>> function through void (*)(void), it's not as good a candidate.
>>
>> Another reason why I think a protoype-less function is a good
>> choice is because the alias and ifunc attributes already use it
>> as an escape mechanism from their type incompatibility warning.
>>
> 
> I know of pre-existing code-bases where a type-cast to type:
> void (*) (void);
> 
> .. is already used as a generic function pointer: libffi and
> libgo, I would not want to break these.
> 
> Actually when I have a type:
> X (*) (...);
> 
> I would like to make sure that the warning checks that
> only functions returning X are assigned.
> 
> and for X (*) (Y, ....);
> 
> I would like to check that anything returning X with
> first argument of type Y is assigned.
> 
> There are code bases where such a scheme is used.
> For instance one that I myself maintain: the OPC/UA AnsiC Stack,
> where I have this type definition:
> 
> typedef OpcUa_StatusCode (OpcUa_PfnInvokeService)(OpcUa_Endpoint
> hEndpoint, ...);
> 
> And this plays well together with this warning, because only
> functions are assigned that match up to the ...);
> Afterwards this pointer is cast back to the original signature,
> so everything is perfectly fine.
> 
> Regarding the cast from pointer to member to function, I see also a
> warning without -Wpedantic:
> Warnung: converting from »void (S::*)(int*)« to »void (*)(int*)«
> [-Wpmf-conversions]
>      F *pf = (F*)&S::foo;
>                      ^~~
> 
> And this one is even default-enabled, so I think that should be
> more than sufficient.
> 
> I also changed the heuristic, so that your example with the enum should
> now work.  I did not add it to the test case, because it would
> break with -fshort-enums :(
> 
> Attached I have an updated patch that extends this warning to the
> pointer-to-member function cast, and relaxes the heuristic on the
> benign integral type differences a bit further.
> 
> 
> Is it OK for trunk after bootstrap and reg-testing?
> 
> 
> Thanks
> Bernd.
> 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]