From 0d590d21586edbb9c62ce3db92794d93faf7ed34 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek <jakub@redhat.com> Date: Mon, 24 Feb 2025 09:20:47 +0100 Subject: [PATCH] Use nonnull_if_nonzero attribute rather than nonnull on various builtins [PR117023] On top of the https://gcc.gnu.org/pipermail/gcc-patches/2024-November/668554.html https://gcc.gnu.org/pipermail/gcc-patches/2024-November/668699.html https://gcc.gnu.org/pipermail/gcc-patches/2024-November/668700.html patches the following patch adds nonnull_if_nonzero attribute(s) to various builtins instead of or in addition to nonnull attribute. The patch adjusts builtins (when we have them) corresponding to the APIs mentioned in the C2Y N3322 paper: 1) strndup and memset get one nonnull_if_nonzero attribute instead of nonnull 2) memcpy, memmove, strncpy, memcmp, strncmp get two nonnull_if_nonzero attributes instead of nonnull 3) strncat has nonnull without argument changed to nonnull (1) and gets one nonnull_if_nonzero for the src argument (maybe it needs to be clarified in C2Y, but I really think first argument to strncat and wcsncat shouldn't be NULL even for n == 0, because NULL doesn't point to NULL terminated string and one can't append anything to it; and various implementations in the wild including glibc will crash with NULL first argument (x86_64 avx+ doesn't though) Such changes are done also to the _chk suffixed counterparts of the builtins. Furthermore I've changed a couple of builtins for POSIX functions which aren't covered by ISO C, but I'd expect if/when POSIX incorporates C2Y it would do the same changes. In particular 4) strnlen gets one nonnull_if_nonzero instead of nonnull 5) mempcpy and stpncpy get two nonnull_if_nonzero instead of nonnull and lose returns_nonnull attribute; this is kind of unfortunate but I think in the spirit of N3322 mempcpy (NULL, src, 0) should return NULL (i.e. dest + n aka NULL + 0, now valid) and it is hard to express returns non-NULL if first argument is non-NULL or third argument is non-zero I'm not really sure about fread/fwrite, N3322 doesn't mention those, can the first argument be NULL if third argument is 0? What about if second argument is 0? Can the fourth argument be NULL in such cases? And of course, when not using builtins the glibc headers will affect stuff too, so we'll need to wait for N3322 implementation there too (possibly by dropping the nonnull attributes and perhaps conditionally replacing them with this new one if the compiler supports them). 2025-02-24 Jakub Jelinek <jakub@redhat.com> PR c/117023 gcc/ * builtin-attrs.def (ATTR_NONNULL_IF_NONZERO): New DEF_ATTR_IDENT. (ATTR_NOTHROW_NONNULL_IF12_LEAF, ATTR_NOTHROW_NONNULL_IF13_LEAF, ATTR_NOTHROW_NONNULL_IF123_LEAF, ATTR_NOTHROW_NONNULL_IF23_LEAF, ATTR_NOTHROW_NONNULL_1_IF23_LEAF, ATTR_PURE_NOTHROW_NONNULL_IF12_LEAF, ATTR_PURE_NOTHROW_NONNULL_IF13_LEAF, ATTR_PURE_NOTHROW_NONNULL_IF123_LEAF, ATTR_WARN_UNUSED_RESULT_NOTHROW_NONNULL_IF12_LEAF, ATTR_MALLOC_WARN_UNUSED_RESULT_NOTHROW_NONNULL_IF12_LEAF): New DEF_ATTR_TREE_LIST. * builtins.def (BUILT_IN_STRNDUP): Use ATTR_MALLOC_WARN_UNUSED_RESULT_NOTHROW_NONNULL_IF12_LEAF instead of ATTR_MALLOC_WARN_UNUSED_RESULT_NOTHROW_NONNULL_LEAF. (BUILT_IN_STRNCAT, BUILT_IN_STRNCAT_CHK): Use ATTR_NOTHROW_NONNULL_1_IF23_LEAF instead of ATTR_NOTHROW_NONNULL_LEAF. (BUILT_IN_BCOPY, BUILT_IN_MEMCPY, BUILT_IN_MEMCPY_CHK, BUILT_IN_MEMMOVE, BUILT_IN_MEMMOVE_CHK, BUILT_IN_STRNCPY, BUILT_IN_STRNCPY_CHK): Use ATTR_NOTHROW_NONNULL_IF123_LEAF instead of ATTR_NOTHROW_NONNULL_LEAF. (BUILT_IN_MEMPCPY, BUILT_IN_MEMPCPY_CHK, BUILT_IN_STPNCPY, BUILT_IN_STPNCPY_CHK): Use ATTR_NOTHROW_NONNULL_IF123_LEAF instead of ATTR_RETNONNULL_NOTHROW_LEAF. (BUILT_IN_BZERO, BUILT_IN_MEMSET, BUILT_IN_MEMSET_CHK): Use ATTR_NOTHROW_NONNULL_IF13_LEAF instead of ATTR_NOTHROW_NONNULL_LEAF. (BUILT_IN_BCMP, BUILT_IN_MEMCMP, BUILT_IN_STRNCASECMP, BUILT_IN_STRNCMP): Use ATTR_PURE_NOTHROW_NONNULL_IF123_LEAF instead of ATTR_PURE_NOTHROW_NONNULL_LEAF. (BUILT_IN_STRNLEN): Use ATTR_PURE_NOTHROW_NONNULL_IF12_LEAF instead of ATTR_PURE_NOTHROW_NONNULL_LEAF. (BUILT_IN_MEMCHR): Use ATTR_PURE_NOTHROW_NONNULL_IF13_LEAF instead of ATTR_PURE_NOTHROW_NONNULL_LEAF. gcc/testsuite/ * gcc.dg/builtins-nonnull.c (test_memfuncs, test_memfuncs_chk, test_strfuncs, test_strfuncs_chk): Add if (n == 0) return; at the start of the functions. * gcc.dg/Wnonnull-2.c: Copy __builtin_* call statements where appropriate 3 times, once with 0 length, once with n and once with non-zero constant and expect warning only in the third case. Formatting fixes. * gcc.dg/Wnonnull-3.c: Copy __builtin_* call statements where appropriate 3 times, once with 0 length, once with n and once with n guarded with n != 0 and expect warning only in the third case. Formatting fixes. * gcc.dg/nonnull-3.c (foo): Use 16 instead of 0 in the calls added for PR80936. * gcc.dg/nonnull-11.c: New test. * c-c++-common/ubsan/nonnull-1.c: Don't expect runtime diagnostics for the __builtin_memcpy call. * gcc.dg/tree-ssa/pr78154.c (f): Add dn argument and return early if it is NULL. Duplicate cases of builtins which have the first argument changed from nonnull to nonnull_if_nonzero except stpncpy, once with dn as first argument instead of d and once with constant non-zero count rather than n. Disable the stpncpy non-null check. * gcc.dg/Wbuiltin-declaration-mismatch-14.c (test_builtin_calls): Triplicate the strncmp calls, once with 1 last argument and expect warning, once with n last argument and don't expect warning and once with 0 last argument and don't expect warning. * gcc.dg/Wbuiltin-declaration-mismatch-15.c (test_builtin_calls_fe): Likewise. --- gcc/builtin-attrs.def | 29 ++++ gcc/builtins.def | 46 +++---- gcc/testsuite/c-c++-common/ubsan/nonnull-1.c | 3 +- .../gcc.dg/Wbuiltin-declaration-mismatch-14.c | 10 +- .../gcc.dg/Wbuiltin-declaration-mismatch-15.c | 10 +- gcc/testsuite/gcc.dg/Wnonnull-2.c | 110 +++++++++++++--- gcc/testsuite/gcc.dg/Wnonnull-3.c | 124 ++++++++++++++++-- gcc/testsuite/gcc.dg/builtins-nonnull.c | 12 ++ gcc/testsuite/gcc.dg/nonnull-11.c | 56 ++++++++ gcc/testsuite/gcc.dg/nonnull-3.c | 10 +- gcc/testsuite/gcc.dg/tree-ssa/pr78154.c | 33 ++++- 11 files changed, 370 insertions(+), 73 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/nonnull-11.c diff --git a/gcc/builtin-attrs.def b/gcc/builtin-attrs.def index 7af5e92cbd0f..850efea11ca0 100644 --- a/gcc/builtin-attrs.def +++ b/gcc/builtin-attrs.def @@ -100,6 +100,7 @@ DEF_ATTR_IDENT (ATTR_FORMAT, "format") DEF_ATTR_IDENT (ATTR_FORMAT_ARG, "format_arg") DEF_ATTR_IDENT (ATTR_MALLOC, "malloc") DEF_ATTR_IDENT (ATTR_NONNULL, "nonnull") +DEF_ATTR_IDENT (ATTR_NONNULL_IF_NONZERO, "nonnull_if_nonzero") DEF_ATTR_IDENT (ATTR_NORETURN, "noreturn") DEF_ATTR_IDENT (ATTR_NOTHROW, "nothrow") DEF_ATTR_IDENT (ATTR_LEAF, "leaf") @@ -233,6 +234,18 @@ DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_4, ATTR_NONNULL, ATTR_LIST_4, \ /* Nothrow functions whose fifth parameter is a nonnull pointer. */ DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_5, ATTR_NONNULL, ATTR_LIST_5, \ ATTR_NOTHROW_LIST) +/* Nothrow leaf functions whose selected pointer parameter(s) are conditionally + nonnull. */ +DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_IF12_LEAF, ATTR_NONNULL_IF_NONZERO, \ + ATTR_LIST_1_2, ATTR_NOTHROW_LEAF_LIST) +DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_IF13_LEAF, ATTR_NONNULL_IF_NONZERO, \ + ATTR_LIST_1_3, ATTR_NOTHROW_LEAF_LIST) +DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_IF123_LEAF, ATTR_NONNULL_IF_NONZERO, \ + ATTR_LIST_2_3, ATTR_NOTHROW_NONNULL_IF13_LEAF) +DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_IF23_LEAF, ATTR_NONNULL_IF_NONZERO, \ + ATTR_LIST_2_3, ATTR_NOTHROW_LEAF_LIST) +DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_1_IF23_LEAF, ATTR_NONNULL, \ + ATTR_LIST_1, ATTR_NOTHROW_NONNULL_IF23_LEAF) /* Same as ATTR_NONNULL_1. */ DEF_ATTR_TREE_LIST (ATTR_NONNULL_1_1, ATTR_NONNULL, ATTR_LIST_1, ATTR_NULL) @@ -300,6 +313,14 @@ DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_NONNULL, ATTR_PURE, ATTR_NULL, \ /* Nothrow pure leaf functions whose pointer parameter(s) are all nonnull. */ DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_NONNULL_LEAF, ATTR_PURE, ATTR_NULL, \ ATTR_NOTHROW_NONNULL_LEAF) +/* Nothrow pure leaf functions whose selected pointer parameter(s) are + conditionally nonnull. */ +DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_NONNULL_IF12_LEAF, ATTR_PURE, ATTR_NULL, \ + ATTR_NOTHROW_NONNULL_IF12_LEAF) +DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_NONNULL_IF13_LEAF, ATTR_PURE, ATTR_NULL, \ + ATTR_NOTHROW_NONNULL_IF13_LEAF) +DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_NONNULL_IF123_LEAF, ATTR_PURE, ATTR_NULL, \ + ATTR_NOTHROW_NONNULL_IF123_LEAF) /* Nothrow malloc functions whose pointer parameter(s) are all nonnull. */ DEF_ATTR_TREE_LIST (ATTR_WARN_UNUSED_RESULT_NOTHROW_NONNULL, ATTR_WARN_UNUSED_RESULT, ATTR_NULL, \ ATTR_NOTHROW_NONNULL) @@ -310,6 +331,14 @@ DEF_ATTR_TREE_LIST (ATTR_WARN_UNUSED_RESULT_NOTHROW_NONNULL_LEAF, ATTR_WARN_UNUS ATTR_NOTHROW_NONNULL_LEAF) DEF_ATTR_TREE_LIST (ATTR_MALLOC_WARN_UNUSED_RESULT_NOTHROW_NONNULL_LEAF, ATTR_MALLOC, ATTR_NULL, \ ATTR_WARN_UNUSED_RESULT_NOTHROW_NONNULL_LEAF) +/* Nothrow malloc leaf functions whose selected pointer parameter(s) are + conditionally nonnull. */ +DEF_ATTR_TREE_LIST (ATTR_WARN_UNUSED_RESULT_NOTHROW_NONNULL_IF12_LEAF, \ + ATTR_WARN_UNUSED_RESULT, ATTR_NULL, \ + ATTR_NOTHROW_NONNULL_IF12_LEAF) +DEF_ATTR_TREE_LIST (ATTR_MALLOC_WARN_UNUSED_RESULT_NOTHROW_NONNULL_IF12_LEAF, \ + ATTR_MALLOC, ATTR_NULL, \ + ATTR_WARN_UNUSED_RESULT_NOTHROW_NONNULL_IF12_LEAF) /* Construct a tree for the format attribute (and implicitly nonnull). */ #define DEF_FORMAT_ATTRIBUTE(TYPE, FA, VALUES) \ diff --git a/gcc/builtins.def b/gcc/builtins.def index 89fc74654ca7..ff470051e54e 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -846,19 +846,19 @@ DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_CTAN, "ctan", CPROJ_TYPE, ATTR_MATHFN_F #undef CPROJ_TYPE /* Category: string/memory builtins. */ -DEF_EXT_LIB_BUILTIN (BUILT_IN_BCMP, "bcmp", BT_FN_INT_CONST_PTR_CONST_PTR_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF) -DEF_EXT_LIB_BUILTIN (BUILT_IN_BCOPY, "bcopy", BT_FN_VOID_CONST_PTR_PTR_SIZE, ATTR_NOTHROW_NONNULL_LEAF) -DEF_EXT_LIB_BUILTIN (BUILT_IN_BZERO, "bzero", BT_FN_VOID_PTR_SIZE, ATTR_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_BCMP, "bcmp", BT_FN_INT_CONST_PTR_CONST_PTR_SIZE, ATTR_PURE_NOTHROW_NONNULL_IF123_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_BCOPY, "bcopy", BT_FN_VOID_CONST_PTR_PTR_SIZE, ATTR_NOTHROW_NONNULL_IF123_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_BZERO, "bzero", BT_FN_VOID_PTR_SIZE, ATTR_NOTHROW_NONNULL_IF12_LEAF) DEF_EXT_LIB_BUILTIN (BUILT_IN_INDEX, "index", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF) -DEF_LIB_BUILTIN (BUILT_IN_MEMCHR, "memchr", BT_FN_PTR_CONST_PTR_INT_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF) -DEF_LIB_BUILTIN (BUILT_IN_MEMCMP, "memcmp", BT_FN_INT_CONST_PTR_CONST_PTR_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF) -DEF_LIB_BUILTIN (BUILT_IN_MEMCPY, "memcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_LEAF) -DEF_LIB_BUILTIN (BUILT_IN_MEMMOVE, "memmove", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_LEAF) -DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMPCPY, "mempcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RETNONNULL_NOTHROW_LEAF) -DEF_LIB_BUILTIN (BUILT_IN_MEMSET, "memset", BT_FN_PTR_PTR_INT_SIZE, ATTR_NOTHROW_NONNULL_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_MEMCHR, "memchr", BT_FN_PTR_CONST_PTR_INT_SIZE, ATTR_PURE_NOTHROW_NONNULL_IF13_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_MEMCMP, "memcmp", BT_FN_INT_CONST_PTR_CONST_PTR_SIZE, ATTR_PURE_NOTHROW_NONNULL_IF123_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_MEMCPY, "memcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_IF123_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_MEMMOVE, "memmove", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_IF123_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMPCPY, "mempcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_IF123_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_MEMSET, "memset", BT_FN_PTR_PTR_INT_SIZE, ATTR_NOTHROW_NONNULL_IF13_LEAF) DEF_EXT_LIB_BUILTIN (BUILT_IN_RINDEX, "rindex", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF) DEF_EXT_LIB_BUILTIN (BUILT_IN_STPCPY, "stpcpy", BT_FN_STRING_STRING_CONST_STRING, ATTR_RETNONNULL_NOTHROW_LEAF) -DEF_EXT_LIB_BUILTIN (BUILT_IN_STPNCPY, "stpncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_RETNONNULL_NOTHROW_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_STPNCPY, "stpncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_IF123_LEAF) DEF_EXT_LIB_BUILTIN (BUILT_IN_STRCASECMP, "strcasecmp", BT_FN_INT_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF) DEF_LIB_BUILTIN (BUILT_IN_STRCAT, "strcat", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL_LEAF) DEF_LIB_BUILTIN (BUILT_IN_STRCHR, "strchr", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF) @@ -866,13 +866,13 @@ DEF_LIB_BUILTIN (BUILT_IN_STRCMP, "strcmp", BT_FN_INT_CONST_STRING_CONST_ DEF_LIB_BUILTIN (BUILT_IN_STRCPY, "strcpy", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL_LEAF) DEF_LIB_BUILTIN (BUILT_IN_STRCSPN, "strcspn", BT_FN_SIZE_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF) DEF_C23_BUILTIN (BUILT_IN_STRDUP, "strdup", BT_FN_STRING_CONST_STRING, ATTR_MALLOC_WARN_UNUSED_RESULT_NOTHROW_NONNULL_LEAF) -DEF_C23_BUILTIN (BUILT_IN_STRNDUP, "strndup", BT_FN_STRING_CONST_STRING_SIZE, ATTR_MALLOC_WARN_UNUSED_RESULT_NOTHROW_NONNULL_LEAF) +DEF_C23_BUILTIN (BUILT_IN_STRNDUP, "strndup", BT_FN_STRING_CONST_STRING_SIZE, ATTR_MALLOC_WARN_UNUSED_RESULT_NOTHROW_NONNULL_IF12_LEAF) DEF_LIB_BUILTIN (BUILT_IN_STRLEN, "strlen", BT_FN_SIZE_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF) -DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNCASECMP, "strncasecmp", BT_FN_INT_CONST_STRING_CONST_STRING_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF) -DEF_LIB_BUILTIN (BUILT_IN_STRNCAT, "strncat", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF) -DEF_LIB_BUILTIN (BUILT_IN_STRNCMP, "strncmp", BT_FN_INT_CONST_STRING_CONST_STRING_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF) -DEF_LIB_BUILTIN (BUILT_IN_STRNCPY, "strncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF) -DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNLEN, "strnlen", BT_FN_SIZE_CONST_STRING_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNCASECMP, "strncasecmp", BT_FN_INT_CONST_STRING_CONST_STRING_SIZE, ATTR_PURE_NOTHROW_NONNULL_IF123_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_STRNCAT, "strncat", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_1_IF23_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_STRNCMP, "strncmp", BT_FN_INT_CONST_STRING_CONST_STRING_SIZE, ATTR_PURE_NOTHROW_NONNULL_IF123_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_STRNCPY, "strncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_IF123_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNLEN, "strnlen", BT_FN_SIZE_CONST_STRING_SIZE, ATTR_PURE_NOTHROW_NONNULL_IF12_LEAF) DEF_LIB_BUILTIN (BUILT_IN_STRPBRK, "strpbrk", BT_FN_STRING_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF) DEF_LIB_BUILTIN (BUILT_IN_STRRCHR, "strrchr", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF) DEF_LIB_BUILTIN (BUILT_IN_STRSPN, "strspn", BT_FN_SIZE_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF) @@ -1148,16 +1148,16 @@ DEF_BUILTIN_STUB (BUILT_IN_STRNCMP_EQ, "__builtin_strncmp_eq") /* Object size checking builtins. */ DEF_GCC_BUILTIN (BUILT_IN_OBJECT_SIZE, "object_size", BT_FN_SIZE_CONST_PTR_INT, ATTR_CONST_NOTHROW_LEAF_LIST) DEF_GCC_BUILTIN (BUILT_IN_DYNAMIC_OBJECT_SIZE, "dynamic_object_size", BT_FN_SIZE_CONST_PTR_INT, ATTR_PURE_NOTHROW_LEAF_LIST) -DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMCPY_CHK, "__memcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF) -DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMMOVE_CHK, "__memmove_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF) -DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMPCPY_CHK, "__mempcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_RETNONNULL_NOTHROW_LEAF) -DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMSET_CHK, "__memset_chk", BT_FN_PTR_PTR_INT_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMCPY_CHK, "__memcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_NOTHROW_NONNULL_IF123_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMMOVE_CHK, "__memmove_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_NOTHROW_NONNULL_IF123_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMPCPY_CHK, "__mempcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_NOTHROW_NONNULL_IF123_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMSET_CHK, "__memset_chk", BT_FN_PTR_PTR_INT_SIZE_SIZE, ATTR_NOTHROW_NONNULL_IF13_LEAF) DEF_EXT_LIB_BUILTIN (BUILT_IN_STPCPY_CHK, "__stpcpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_RETNONNULL_NOTHROW_LEAF) -DEF_EXT_LIB_BUILTIN (BUILT_IN_STPNCPY_CHK, "__stpncpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_RETNONNULL_NOTHROW_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_STPNCPY_CHK, "__stpncpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL_IF123_LEAF) DEF_EXT_LIB_BUILTIN (BUILT_IN_STRCAT_CHK, "__strcat_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF) DEF_EXT_LIB_BUILTIN (BUILT_IN_STRCPY_CHK, "__strcpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF) -DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNCAT_CHK, "__strncat_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF) -DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNCPY_CHK, "__strncpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNCAT_CHK, "__strncat_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL_1_IF23_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNCPY_CHK, "__strncpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL_IF123_LEAF) DEF_EXT_LIB_BUILTIN (BUILT_IN_SNPRINTF_CHK, "__snprintf_chk", BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_NOTHROW_5_6) DEF_EXT_LIB_BUILTIN (BUILT_IN_SPRINTF_CHK, "__sprintf_chk", BT_FN_INT_STRING_INT_SIZE_CONST_STRING_VAR, ATTR_NOTHROW_NONNULL_1_FORMAT_PRINTF_4_5) DEF_EXT_LIB_BUILTIN (BUILT_IN_VSNPRINTF_CHK, "__vsnprintf_chk", BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_NOTHROW_5_0) diff --git a/gcc/testsuite/c-c++-common/ubsan/nonnull-1.c b/gcc/testsuite/c-c++-common/ubsan/nonnull-1.c index d3063ca4a6fc..635ffdc4b712 100644 --- a/gcc/testsuite/c-c++-common/ubsan/nonnull-1.c +++ b/gcc/testsuite/c-c++-common/ubsan/nonnull-1.c @@ -34,5 +34,4 @@ main () /* { dg-output "\.c:13:\[0-9]*:\[^\n\r]*null pointer returned from function declared to never return null\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output "\[^\n\r]*\.c:29:\[0-9]*:\[^\n\r]*null pointer passed as argument 1, which is declared to never be null\[^\n\r]*(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*\.c:30:\[0-9]*:\[^\n\r]*null pointer passed as argument 3, which is declared to never be null\[^\n\r]*(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*\.c:31:\[0-9]*:\[^\n\r]*null pointer passed as argument 1, which is declared to never be null" } */ +/* { dg-output "\[^\n\r]*\.c:30:\[0-9]*:\[^\n\r]*null pointer passed as argument 3, which is declared to never be null" } */ diff --git a/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-14.c b/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-14.c index cc536d714313..f361550c1e29 100644 --- a/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-14.c +++ b/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-14.c @@ -45,8 +45,14 @@ int test_builtin_calls (size_t n) r += strcmp ((char*)0, ""); // { dg-warning "\\\[-Wnonnull]" } r += strcmp ("", (char*)0); // { dg-warning "\\\[-Wnonnull]" } - r += strncmp ((char*)0, "", n); // { dg-warning "\\\[-Wnonnull]" } - r += strncmp ("", (char*)0, n); // { dg-warning "\\\[-Wnonnull]" } + r += strncmp ((char*)0, "", 1); // { dg-warning "\\\[-Wnonnull]" } + r += strncmp ("", (char*)0, 1); // { dg-warning "\\\[-Wnonnull]" } + + r += strncmp ((char*)0, "", n); + r += strncmp ("", (char*)0, n); + + r += strncmp ((char*)0, "", 0); + r += strncmp ("", (char*)0, 0); return r; } diff --git a/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-15.c b/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-15.c index 3c32a5fc5455..e9750cfb94f2 100644 --- a/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-15.c +++ b/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-15.c @@ -30,8 +30,14 @@ int test_builtin_calls_fe (size_t n) r += strcmp ((char*)0, ""); // { dg-warning "\\\[-Wnonnull]" } r += strcmp ("", (char*)0); // { dg-warning "\\\[-Wnonnull]" } - r += strncmp ((char*)0, "", n); // { dg-warning "\\\[-Wnonnull]" } - r += strncmp ("", (char*)0, n); // { dg-warning "\\\[-Wnonnull]" } + r += strncmp ((char*)0, "", 1); // { dg-warning "\\\[-Wnonnull]" } + r += strncmp ("", (char*)0, 1); // { dg-warning "\\\[-Wnonnull]" } + + r += strncmp ((char*)0, "", n); + r += strncmp ("", (char*)0, n); + + r += strncmp ((char*)0, "", 0); + r += strncmp ("", (char*)0, 0); r += strlen ((char*)0); // { dg-warning "\\\[-Wnonnull]" } return r; diff --git a/gcc/testsuite/gcc.dg/Wnonnull-2.c b/gcc/testsuite/gcc.dg/Wnonnull-2.c index d870473d5a92..646c460bdbb6 100644 --- a/gcc/testsuite/gcc.dg/Wnonnull-2.c +++ b/gcc/testsuite/gcc.dg/Wnonnull-2.c @@ -4,52 +4,122 @@ { dg-do compile } { dg-options "-O0 -Wall" } */ -void zero0 (void *p, unsigned n) +void +zero0 (void *p, unsigned n) { - __builtin_memset (0, 0, n); // { dg-warning "\\\[-Wnonnull]" } + __builtin_memset (0, 0, 0); + __builtin_memset (0, 0, n); + __builtin_memset (0, 0, 1); // { dg-warning "\\\[-Wnonnull]" } } -void zero1 (void *p, unsigned n) +void +zero1 (void *p, unsigned n) { - __builtin_bzero (0, n); // { dg-warning "\\\[-Wnonnull]" } + __builtin_bzero (0, 0); + __builtin_bzero (0, n); + __builtin_bzero (0, 2); // { dg-warning "\\\[-Wnonnull]" } } -void copy0 (void *p, const void *q, unsigned n) +void +copy0 (void *p, const void *q, unsigned n) { - __builtin_memcpy (0, q, n); // { dg-warning "\\\[-Wnonnull]" } + __builtin_memcpy (0, q, 0); + __builtin_memcpy (0, q, n); + __builtin_memcpy (0, q, 3); // { dg-warning "\\\[-Wnonnull]" } } -void copy1 (void *p, const void *q, unsigned n) +void +copy1 (void *p, const void *q, unsigned n) { - __builtin_memcpy (0, q, n); // { dg-warning "\\\[-Wnonnull]" } + __builtin_memcpy (p, 0, 0); + __builtin_memcpy (p, 0, n); + __builtin_memcpy (p, 0, 4); // { dg-warning "\\\[-Wnonnull]" } } -void copy2 (void *p, const void *q, unsigned n) +void +copy2 (void *p, const void *q, unsigned n) { - __builtin_bcopy (q, 0, n); // { dg-warning "\\\[-Wnonnull]" } + __builtin_bcopy (0, p, 0); + __builtin_bcopy (0, p, n); + __builtin_bcopy (0, p, 5); // { dg-warning "\\\[-Wnonnull]" } } -void copy3 (void *p, const void *q, unsigned n) +void +copy3 (void *p, const void *q, unsigned n) { - __builtin_bcopy (q, 0, n); // { dg-warning "\\\[-Wnonnull]" } + __builtin_bcopy (q, 0, 0); + __builtin_bcopy (q, 0, n); + __builtin_bcopy (q, 0, 6); // { dg-warning "\\\[-Wnonnull]" } } -int cmp0 (const void *p, const void *q, unsigned n) +int +cmp0 (const void *p, const void *q, unsigned n) { - return __builtin_memcmp (0, q, n); // { dg-warning "\\\[-Wnonnull]" } + return __builtin_memcmp (0, q, 0); } -int cmp1 (const void *p, const void *q, unsigned n) +int +cmp1 (const void *p, const void *q, unsigned n) { - return __builtin_memcmp (0, q, n); // { dg-warning "\\\[-Wnonnull]" } + return __builtin_memcmp (0, q, 0); } -int cmp2 (const void *p, const void *q, unsigned n) +int +cmp2 (const void *p, const void *q, unsigned n) { - return __builtin_bcmp (0, q, n); // { dg-warning "\\\[-Wnonnull]" } + return __builtin_bcmp (0, q, 0); } -int cmp3 (const void *p, const void *q, unsigned n) +int +cmp3 (const void *p, const void *q, unsigned n) { - return __builtin_bcmp (p, 0, n); // { dg-warning "\\\[-Wnonnull]" } + return __builtin_bcmp (p, 0, 0); +} + +int +cmp4 (const void *p, const void *q, unsigned n) +{ + return __builtin_memcmp (0, q, n); +} + +int +cmp5 (const void *p, const void *q, unsigned n) +{ + return __builtin_memcmp (0, q, n); +} + +int +cmp6 (const void *p, const void *q, unsigned n) +{ + return __builtin_bcmp (0, q, n); +} + +int +cmp7 (const void *p, const void *q, unsigned n) +{ + return __builtin_bcmp (p, 0, n); +} + +int +cmp8 (const void *p, const void *q, unsigned n) +{ + return __builtin_memcmp (0, q, 41); // { dg-warning "\\\[-Wnonnull]" } +} + +int +cmp9 (const void *p, const void *q, unsigned n) +{ + return __builtin_memcmp (0, q, 42); // { dg-warning "\\\[-Wnonnull]" } +} + +int +cmp10 (const void *p, const void *q, unsigned n) +{ + return __builtin_bcmp (0, q, 43); // { dg-warning "\\\[-Wnonnull]" } +} + +int +cmp11 (const void *p, const void *q, unsigned n) +{ + return __builtin_bcmp (p, 0, 44); // { dg-warning "\\\[-Wnonnull]" } } diff --git a/gcc/testsuite/gcc.dg/Wnonnull-3.c b/gcc/testsuite/gcc.dg/Wnonnull-3.c index ad016df93319..b11c9dcf1a29 100644 --- a/gcc/testsuite/gcc.dg/Wnonnull-3.c +++ b/gcc/testsuite/gcc.dg/Wnonnull-3.c @@ -6,66 +6,164 @@ #define NOIPA __attribute__ ((noipa)) -NOIPA void zero0 (void *p, unsigned n) +NOIPA void +zero0 (void *p, unsigned n) { if (p == 0) + __builtin_memset (p, 0, 0); + if (p == 0) + __builtin_memset (p, 0, n); + if (p == 0 && n != 0) __builtin_memset (p, 0, n); // { dg-warning "\\\[-Wnonnull]" } } -NOIPA void zero1 (void *p, unsigned n) +NOIPA void +zero1 (void *p, unsigned n) { if (p == 0) + __builtin_bzero (p, 0); + if (p == 0) + __builtin_bzero (p, n); + if (p == 0 && n != 0) __builtin_bzero (p, n); // { dg-warning "\\\[-Wnonnull]" } } -NOIPA void copy0 (void *p, const void *q, unsigned n) +NOIPA void +copy0 (void *p, const void *q, unsigned n) { if (p == 0) + __builtin_memcpy (p, q, 0); + if (p == 0) + __builtin_memcpy (p, q, n); + if (p == 0 && n != 0) __builtin_memcpy (p, q, n); // { dg-warning "\\\[-Wnonnull]" } } -NOIPA void copy1 (void *p, const void *q, unsigned n) +NOIPA void +copy1 (void *p, const void *q, unsigned n) { if (q == 0) + __builtin_memcpy (p, q, 0); + if (q == 0) + __builtin_memcpy (p, q, n); + if (q == 0 && n != 0) __builtin_memcpy (p, q, n); // { dg-warning "\\\[-Wnonnull]" } } -NOIPA void copy2 (void *p, const void *q, unsigned n) +NOIPA void +copy2 (void *p, const void *q, unsigned n) { if (p == 0) + __builtin_bcopy (q, p, 0); + if (p == 0) + __builtin_bcopy (q, p, n); + if (p == 0 && n != 0) __builtin_bcopy (q, p, n); // { dg-warning "\\\[-Wnonnull]" } } -NOIPA void copy3 (void *p, const void *q, unsigned n) +NOIPA void +copy3 (void *p, const void *q, unsigned n) { if (q == 0) + __builtin_bcopy (q, p, 0); + if (q == 0) + __builtin_bcopy (q, p, n); + if (q == 0 && n != 0) __builtin_bcopy (q, p, n); // { dg-warning "\\\[-Wnonnull]" } } -NOIPA int cmp0 (const void *p, const void *q, unsigned n) +NOIPA int +cmp0 (const void *p, const void *q, unsigned n) { if (p == 0) - return __builtin_memcmp (p, q, n); // { dg-warning "\\\[-Wnonnull]" } + return __builtin_memcmp (p, q, 0); return 0; } -NOIPA int cmp1 (const void *p, const void *q, unsigned n) +NOIPA int +cmp1 (const void *p, const void *q, unsigned n) { if (q == 0) - return __builtin_memcmp (p, q, n); // { dg-warning "\\\[-Wnonnull]" } + return __builtin_memcmp (p, q, 0); return 0; } -NOIPA int cmp2 (const void *p, const void *q, unsigned n) +NOIPA int +cmp2 (const void *p, const void *q, unsigned n) { if (p == 0) - return __builtin_bcmp (p, q, n); // { dg-warning "\\\[-Wnonnull]" } + return __builtin_bcmp (p, q, 0); + return 0; +} + +NOIPA int +cmp3 (const void *p, const void *q, unsigned n) +{ + if (q == 0) + return __builtin_bcmp (p, q, 0); + return 0; +} + +NOIPA int +cmp4 (const void *p, const void *q, unsigned n) +{ + if (p == 0) + return __builtin_memcmp (p, q, n); + return 0; +} + +NOIPA int +cmp5 (const void *p, const void *q, unsigned n) +{ + if (q == 0) + return __builtin_memcmp (p, q, n); return 0; } -NOIPA int cmp3 (const void *p, const void *q, unsigned n) +NOIPA int +cmp6 (const void *p, const void *q, unsigned n) +{ + if (p == 0) + return __builtin_bcmp (p, q, n); + return 0; +} + +NOIPA int +cmp7 (const void *p, const void *q, unsigned n) { if (q == 0) + return __builtin_bcmp (p, q, n); + return 0; +} + +NOIPA int +cmp8 (const void *p, const void *q, unsigned n) +{ + if (p == 0 && n != 0) + return __builtin_memcmp (p, q, n); // { dg-warning "\\\[-Wnonnull]" } + return 0; +} + +NOIPA int +cmp9 (const void *p, const void *q, unsigned n) +{ + if (q == 0 && n != 0) + return __builtin_memcmp (p, q, n); // { dg-warning "\\\[-Wnonnull]" } + return 0; +} + +NOIPA int +cmp10 (const void *p, const void *q, unsigned n) +{ + if (p == 0 && n != 0) + return __builtin_bcmp (p, q, n); // { dg-warning "\\\[-Wnonnull]" } + return 0; +} + +NOIPA int +cmp11 (const void *p, const void *q, unsigned n) +{ + if (q == 0 && n != 0) return __builtin_bcmp (p, q, n); // { dg-warning "\\\[-Wnonnull]" } return 0; } diff --git a/gcc/testsuite/gcc.dg/builtins-nonnull.c b/gcc/testsuite/gcc.dg/builtins-nonnull.c index f8c482e98251..d59579d78c8e 100644 --- a/gcc/testsuite/gcc.dg/builtins-nonnull.c +++ b/gcc/testsuite/gcc.dg/builtins-nonnull.c @@ -24,6 +24,9 @@ void sink (int, ...); void test_memfuncs (void *s, unsigned n) { + if (n == 0) + return; + /* Bzero is not declared attribute nonnull (maybe it should be?) but it's transformed into a call to memset() which is. */ bzero (null (), n); /* { dg-warning "argument 1 null where non-null expected" } */ @@ -51,6 +54,9 @@ void test_memfuncs (void *s, unsigned n) void test_memfuncs_chk (void *s, unsigned n) { + if (n == 0) + return; + T (memcpy (null (), s, n)); /* { dg-warning "argument 1 null where non-null expected" } */ T (memcpy (s, null (), n)); /* { dg-warning "argument 2 null where non-null expected" } */ @@ -76,6 +82,9 @@ void test_memfuncs_chk (void *s, unsigned n) void test_strfuncs (char *s, unsigned n) { + if (n == 0) + return; + T (strcat (null (), s)); /* { dg-warning "argument 1 null where non-null expected" } */ T (strcat (s, null ())); /* { dg-warning "argument 2 null where non-null expected" } */ @@ -119,6 +128,9 @@ void test_strfuncs (char *s, unsigned n) void test_strfuncs_chk (char *s, unsigned n) { + if (n == 0) + return; + T (strcat (null (), s)); /* { dg-warning "argument 1 null where non-null expected" } */ T (strcat (s, null ())); /* { dg-warning "argument 2 null where non-null expected" } */ diff --git a/gcc/testsuite/gcc.dg/nonnull-11.c b/gcc/testsuite/gcc.dg/nonnull-11.c new file mode 100644 index 000000000000..976022aa2249 --- /dev/null +++ b/gcc/testsuite/gcc.dg/nonnull-11.c @@ -0,0 +1,56 @@ +/* Test for the "nonnull" function attribute on builtins. Use the + "__builtin_" style below so we don't need prototypes. */ +/* { dg-do compile } */ +/* { dg-options "-Wnonnull" } */ + +#include <stddef.h> + +void +use (void *x, size_t y) +{ + (void) x; + (void) y; +} + +void * +foo (void *p, char *s) +{ + __builtin_bzero (NULL, 0); + __builtin_bcopy (NULL, p, 0); + __builtin_bcopy (p, NULL, 0); + __builtin_bcmp (NULL, p, 0); + __builtin_bcmp (p, NULL, 0); + + __builtin_memcpy (p, NULL, 0); + __builtin_memcpy (NULL, p, 0); + __builtin_memmove (p, NULL, 0); + __builtin_memmove (NULL, p, 0); + __builtin_memcmp (p, NULL, 0); + __builtin_memcmp (NULL, p, 0); + __builtin_memset (NULL, 0, 0); + __builtin_mempcpy (p, NULL, 0); + __builtin_mempcpy (NULL, p, 0); + + __builtin_strncat (NULL, s, 0); /* { dg-warning "null" "null pointer check" } */ + __builtin_strncat (s, NULL, 0); + __builtin_stpncpy (NULL, s, 0); + __builtin_stpncpy (s, NULL, 0); + __builtin_strncpy (NULL, s, 0); + __builtin_strncpy (s, NULL, 0); + __builtin_strncasecmp (NULL, s, 0); + __builtin_strncasecmp (s, NULL, 0); + __builtin_strncmp (NULL, s, 0); + __builtin_strncmp (s, NULL, 0); + void *p1 = __builtin_strndup (NULL, 0); + + size_t n = __builtin_strnlen (NULL, 16); /* { dg-warning "null" "null pointer check" } */ + use (NULL, n); + n = __builtin_strnlen (NULL, 0); + use (NULL, n); + + void *q = __builtin_memchr (NULL, ' ', 16); /* { dg-warning "null" "null pointer check" } */ + use (q, 0); + q = __builtin_memchr (NULL, ' ', 0); + use (q, 0); + return p1; +} diff --git a/gcc/testsuite/gcc.dg/nonnull-3.c b/gcc/testsuite/gcc.dg/nonnull-3.c index c52fe2c830c8..fc12cb0c3620 100644 --- a/gcc/testsuite/gcc.dg/nonnull-3.c +++ b/gcc/testsuite/gcc.dg/nonnull-3.c @@ -9,11 +9,11 @@ void foo (void *p, char *s) { - __builtin_bzero (NULL, 0); /* { dg-warning "null" "pr80936" } */ - __builtin_bcopy (NULL, p, 0); /* { dg-warning "null" "pr80936" } */ - __builtin_bcopy (p, NULL, 0); /* { dg-warning "null" "pr80936" } */ - __builtin_bcmp (NULL, p, 0); /* { dg-warning "null" "pr80936" } */ - __builtin_bcmp (p, NULL, 0); /* { dg-warning "null" "pr80936" } */ + __builtin_bzero (NULL, 16); /* { dg-warning "null" "pr80936" } */ + __builtin_bcopy (NULL, p, 16); /* { dg-warning "null" "pr80936" } */ + __builtin_bcopy (p, NULL, 16); /* { dg-warning "null" "pr80936" } */ + __builtin_bcmp (NULL, p, 16); /* { dg-warning "null" "pr80936" } */ + __builtin_bcmp (p, NULL, 16); /* { dg-warning "null" "pr80936" } */ __builtin_index (NULL, 16); /* { dg-warning "null" "null pointer check" } */ __builtin_rindex (NULL, 16); /* { dg-warning "null" "null pointer check" } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr78154.c b/gcc/testsuite/gcc.dg/tree-ssa/pr78154.c index 3ba8f64e2664..4fc300792bb6 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr78154.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr78154.c @@ -2,17 +2,20 @@ /* { dg-options "-O2 -fdump-tree-evrp-slim -fdelete-null-pointer-checks" } */ /* { dg-skip-if "" { keeps_null_pointer_checks } } */ -void f(void *d, const void *s, __SIZE_TYPE__ n) +void f(void *d, void *dn, const void *s, __SIZE_TYPE__ n) { - void *t1 = __builtin_memcpy (d, s, n); + if (!dn) + return; + + void *t1 = __builtin_memcpy (dn, s, n); if (t1 == 0) __builtin_abort (); - void *t2 = __builtin_memmove (d, s, n); + void *t2 = __builtin_memmove (dn, s, n); if (t2 == 0) __builtin_abort (); - void *t3 = __builtin_memset (d, 0, n); + void *t3 = __builtin_memset (dn, 0, n); if (t3 == 0) __builtin_abort (); @@ -20,7 +23,7 @@ void f(void *d, const void *s, __SIZE_TYPE__ n) if (t4 == 0) __builtin_abort (); - void *t5 = __builtin_strncpy (d, s, n); + void *t5 = __builtin_strncpy (dn, s, n); if (t5 == 0) __builtin_abort (); @@ -37,7 +40,25 @@ void f(void *d, const void *s, __SIZE_TYPE__ n) __builtin_abort (); void *t9 = __builtin_stpncpy (d, s, n); - if (t9 == 0) + /* We can't handle this one anymore, as stpncpy (NULL, s, 0) + can return NULL and it doesn't always return the first argument. */ + if (0 && t9 == 0) + __builtin_abort (); + + void *t10 = __builtin_memcpy (d, s, 42); + if (t10 == 0) + __builtin_abort (); + + void *t11 = __builtin_memmove (d, s, 42); + if (t11 == 0) + __builtin_abort (); + + void *t12 = __builtin_memset (d, 0, 42); + if (t12 == 0) + __builtin_abort (); + + void *t13 = __builtin_strncpy (d, s, 42); + if (t13 == 0) __builtin_abort (); } -- GitLab