https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117023

--- Comment #6 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jakub Jelinek <ja...@gcc.gnu.org>:

https://gcc.gnu.org/g:19fe55c4801de50deee03b333e94d007aae222e3

commit r15-5750-g19fe55c4801de50deee03b333e94d007aae222e3
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Thu Nov 28 11:48:33 2024 +0100

    Add support for nonnull_if_nonzero attribute [PR117023]

    As mentioned in an earlier thread, C2Y voted in a change which made
    various library APIs callable with NULL arguments in certain cases,
    e.g.
    memcpy (NULL, NULL, 0);
    is now valid, although
    memcpy (NULL, NULL, 1);
    remains invalid.  This affects various APIs, including several of
    GCC builtins; plus on the C library side those APIs are often declared
    with nonnull attribute(s) as well.

    Florian suggested using the access attribute for this, but our docs
    explicitly say that access attribute doesn't imply nonnull and it doesn't
    cover e.g. the qsort case where the comparison function pointer may be
    also NULL if nmemb is 0, but must be non-zero otherwise.
    As this case affects 21 APIs in C standard and I think is going to affect
    various wrappers around those in various packages as well, I think it
    is a common thing that should have its own attribute, because we should
    still warn when people use
    qsort (NULL, 1, 1, NULL);
    etc., and similarly want to have -fsanitize=null instrumentation for those.

    So, the following patch introduces nonnull_if_nonzero attribute (or would
    you prefer cond_nonnull or some other name?), which has always 2 arguments,
    argument index of a pointer argument (like one argument nonnull) and
    argument index of an associated integral argument.  If that argument is
    non-zero, it is UB to pass NULL to the pointer argument, if that argument
    is zero, it is valid.  And changes various spots which already handled the
    nonnull attribute to handle this one as well, with sometimes using the
    ranger (or for -fsanitize=nonnull explicitly checking the associated
    argument value, so instead of if (!ptr) __ubsan_... (...); it will
    now do if (!ptr && sz) __ubsan_... (...);).
    I've so far omitted changing gimple_infer_range (am not 100% sure how I can
    use the ranger inside of the ranger) and changing the analyzer to handle
it.
    And I haven't changed builtins.def etc. to make use of that attribute
    instead of nonnull where appropriate.

    I'd then follow with the builtins.def changes (and eventually glibc
    etc. would need to be adjusted too).

    2024-11-28  Jakub Jelinek  <ja...@redhat.com>

            PR c/117023
    gcc/
            * gimple.h (infer_nonnull_range_by_attribute): Add a tree *
            argument defaulted to NULL.
            * gimple.cc (infer_nonnull_range_by_attribute): Add op2 argument.
            Handle also nonnull_if_nonzero attributes.
            * tree.cc (get_nonnull_args): Fix comment typo.
            * builtins.cc (validate_arglist): Handle nonnull_if_nonzero
attribute.
            * tree-ssa-ccp.cc (pass_post_ipa_warn::execute): Handle
            nonnull_if_nonzero attributes.
            * ubsan.cc (instrument_nonnull_arg): Adjust
            infer_nonnull_range_by_attribute caller.  If it returned true and
            filed in non-NULL arg2, check that arg2 is non-zero as another
            condition next to checking that arg is zero.
            * doc/extend.texi (nonnull_if_nonzero): Document new attribute.
    gcc/c-family/
            * c-attribs.cc (handle_nonnull_if_nonzero_attribute): New
            function.
            (c_common_gnu_attributes): Add nonnull_if_nonzero attribute.
            (handle_nonnull_attribute): Fix comment typo.
            * c-common.cc (struct nonnull_arg_ctx): Add other member.
            (check_function_nonnull): Also check nonnull_if_nonzero attributes.
            (check_nonnull_arg): Use different warning wording if pctx->other
            is non-zero.
            (check_function_arguments): Initialize ctx.other.
    gcc/testsuite/
            * gcc.dg/nonnull-8.c: New test.
            * gcc.dg/nonnull-9.c: New test.
            * gcc.dg/nonnull-10.c: New test.
            * c-c++-common/ubsan/nonnull-6.c: New test.
            * c-c++-common/ubsan/nonnull-7.c: New test.

Reply via email to