[PATCH] add missing attribute nonnull to stdio functions (PR 78673 and 17308)
Jeff Law
law@redhat.com
Wed Dec 14 06:25:00 GMT 2016
On 12/07/2016 08:24 PM, Martin Sebor wrote:
>
> You're right! Good chatch! I missed that there are two ways to
> represent the same thing. For example, these two declarations
>
> void __attribute ((nonnull (1, 2)))
> f (void);
>
> void __attribute ((nonnull (1))) __attribute ((nonnull (2)))
> f (void);
>
> apply to the same arguments but each is represented differently,
> as is this one:
>
> void __attribute ((nonnull))
> f (void);
>
> The builtins use the first form and I didn't have tests for user-
> defined attributes in the second form. I've fixed that in the
> attached updated patch (and added more tests). It does seem,
> though, that it would be better to represent these declarations
> canonically. It would simplify the processing and avoid bugs.
I'm not sure what the historical context is for having two forms of the
same thing. Though I would generally agree that there should be a
canonical form.
One more high level note. While I am in favor of adding these
attributes, they can cause interesting codegen issues that we need to be
on the lookout for.
Specifically when we see an SSA_NAME as an argument when the argument is
marked as NONNULL, the optimizers will try to use that information to
eliminate unnecessary NULL pointer checks.
The canonical example has been
memcpy (src, dst, 0)
[ stuff ]
if (src == 0)
whatever
GCC can sometimes follow things well enough to realize that the test, in
a conforming program, will always be false and remove the test. Some
have claimed this is undesirable behavior on GCC's part (and they may be
right).
Anyway, something to keep in mind. These changes may make GCC ever so
slightly more aggressive in its NULL pointer eliminations.
>
> Thanks
> Martin
>
> gcc-78673.diff
>
>
> PR c/78673 - sprintf missing attribute nonnull on destination argument
> PR c/17308 - nonnull attribute not as useful as it could be
>
> gcc/ChangeLog:
>
> PR c/78673
> PR c/17308
> * builtin-attrs.def (ATTR_NONNULL_1_1, ATTR_NONNULL_1_2): Defined.
> (ATTR_NONNULL_1_3, ATTR_NONNULL_1_4, ATTR_NONNULL_1_5): Same.
> (ATTR_NOTHROW_NONNULL_1_1, ATTR_NOTHROW_NONNULL_1_2): Same.
> (ATTR_NOTHROW_NONNULL_1_3, ATTR_NOTHROW_NONNULL_1_4): Same.
> (ATTR_NOTHROW_NONNULL_1_5): Same.
> (ATTR_NONNULL_1_FORMAT_PRINTF_1_2): Same.
> (ATTR_NONNULL_1_FORMAT_PRINTF_2_0): Same.
> (ATTR_NONNULL_1_FORMAT_PRINTF_2_3): Same.
> (ATTR_NONNULL_1_FORMAT_PRINTF_3_0): Same.
> (ATTR_NONNULL_1_FORMAT_PRINTF_3_4): Same.
> (ATTR_NONNULL_1_FORMAT_PRINTF_4_0): Same.
> (ATTR_NONNULL_1_FORMAT_PRINTF_4_5): Same.
> * builtins.c (validate_arg): Add argument. Treat null pointers
> passed to nonnull arguments as invalid.
> (validate_arglist): Same.
> * builtins.def (fprintf, fprintf_unlocked): Add nonnull attribute.
> (printf, printf_unlocked, sprintf. vfprintf, vsprintf): Same.
> (__sprintf_chk, __vsprintf_chk, __fprintf_chk, __vfprintf_chk): Same.
> * calls.c (get_nonnull_ags, maybe_warn_null_arg): New functions.
> (initialize_argument_information): Diagnose null pointers passed to
> arguments declared nonnull.
> * calls.h (get_nonnull_args): Declared.
>
> gcc/c-family/ChangeLog:
>
> PR c/78673
> PR c/17308
> * c-common.c (check_nonnull_arg): Disable when optimization
> is enabled.
>
> gcc/testsuite/ChangeLog:
>
> PR c/78673
> PR c/17308
> * gcc.dg/builtins-nonnull.c: New test.
> * gcc.dg/nonnull-4.c: New test.
OK.
jeff
More information about the Gcc-patches
mailing list