]> git.ipfire.org Git - thirdparty/gcc.git/commit
Extend nonnull_if_nonzero attribute [PR120520]
authorJakub Jelinek <jakub@redhat.com>
Mon, 30 Jun 2025 09:08:16 +0000 (11:08 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 30 Jun 2025 09:08:16 +0000 (11:08 +0200)
commite33409a83251d057eb03b22e8f95f3ad7bf822e1
treedfa4b68d4a182e2fc5509e5406a49c4a693a87d6
parentda3f2a561649c7c4899449c6b3ab2b6d67792a71
Extend nonnull_if_nonzero attribute [PR120520]

C2Y voted in the
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3466.pdf
paper, which clarifies some of the conditional nonnull cases.
For strncat/__strncat_chk no changes are necessary, we already
use __attribute__((nonnull (1), nonnull_if_nonzero (2, 3))) attributes
on the builtin and glibc can do the same too, meaning that first
argument must be nonnull always and second must be nonnull if
the third one is nonzero.

The problem is with the fread/fwrite changes, where the paper adds:
 If size or nmemb is zero,
+ptr may be a null pointer,
 fread returns zero and the contents of the array and the state of
 the stream remain unchanged.
and ditto for fwrite, so the two argument nonnull_if_nonzero attribute
isn't usable to express that, because whether the pointer can be null
depends on 2 integral arguments rather than one.

The following patch extends the nonnull_if_nonzero attribute, so that
instead of requiring 2 arguments it allows 2 or 3, the first one
is still the pointer argument index which sometimes must not be null
and the other one or two are integral arguments, if there are 2, the
invalid case is only if pointer is null and both the integral arguments
are nonzero.

2025-06-30  Jakub Jelinek  <jakub@redhat.com>

PR c/120520
PR c/117023
gcc/
* builtin-attrs.def (DEF_LIST_INT_INT_INT): Define it and
use for 1,2,3.
(ATTR_NONNULL_IF123_LIST): New DEF_ATTR_TREE_LIST.
(ATTR_NONNULL_4_IF123_LIST): Likewise.
* builtins.def (BUILT_IN_FWRITE): Use ATTR_NONNULL_4_IF123_LIST
instead of ATTR_NONNULL_LIST.
(BUILT_IN_FWRITE_UNLOCKED): Likewise.
* gimple.h (infer_nonnull_range_by_attribute): Add another optional
tree * argument defaulted to NULL.
* gimple.cc (infer_nonnull_range_by_attribute): Add OP3 argument,
handle 3 argument nonnull_if_nonzero attribute.
* builtins.cc (validate_arglist): Handle 3 argument nonnull_if_nonzero
attribute.
* tree-ssa-ccp.cc (pass_post_ipa_warn::execute): Likewise.
* ubsan.cc (instrument_nonnull_arg): Adjust
infer_nonnull_range_by_attribute caller, handle 3 argument
nonnull_if_nonzero attribute.
* gimple-range-infer.cc (gimple_infer_range::gimple_infer_range):
Handle 3 argument nonnull_if_nonzero attribute.
* doc/extend.texi (nonnull_if_nonzero): Document 3 argument version
of the attribute.
gcc/c-family/
* c-attribs.cc (c_common_gnu_attributes): Allow 2 or 3 arguments for
nonnull_if_nonzero attribute instead of only 2.
(handle_nonnull_if_nonzero_attribute): Handle 3 argument
nonnull_if_nonzero.
* c-common.cc (struct nonnull_arg_ctx): Rename other member to other1,
add other2 member.
(check_function_nonnull): Clear a if nonnull attribute has an
argument.  Adjust for nonnull_arg_ctx changes.  Handle 3 argument
nonnull_if_nonzero attribute.
(check_nonnull_arg): Adjust for nonnull_arg_ctx changes, emit different
diagnostics for 3 argument nonnull_if_nonzero attributes.
(check_function_arguments): Adjust ctx var initialization.
gcc/analyzer/
* sm-malloc.cc (malloc_state_machine::on_stmt): Handle 3 argument
nonnull_if_nonzero attribute.
gcc/testsuite/
* gcc.dg/nonnull-9.c: Tweak for 3 argument nonnull_if_nonzero
attribute support, add further tests.
* gcc.dg/nonnull-12.c: New test.
* gcc.dg/nonnull-13.c: New test.
* gcc.dg/nonnull-14.c: New test.
* c-c++-common/ubsan/nonnull-8.c: New test.
* c-c++-common/ubsan/nonnull-9.c: New test.
18 files changed:
gcc/analyzer/sm-malloc.cc
gcc/builtin-attrs.def
gcc/builtins.cc
gcc/builtins.def
gcc/c-family/c-attribs.cc
gcc/c-family/c-common.cc
gcc/doc/extend.texi
gcc/gimple-range-infer.cc
gcc/gimple.cc
gcc/gimple.h
gcc/testsuite/c-c++-common/ubsan/nonnull-8.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/ubsan/nonnull-9.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/nonnull-12.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/nonnull-13.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/nonnull-14.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/nonnull-9.c
gcc/tree-ssa-ccp.cc
gcc/ubsan.cc