diff --git a/gcc/builtin-attrs.def b/gcc/builtin-attrs.def index 7af5e92cbd0f16c358edb7781395f6106f2cb44a..850efea11ca0a59a41002d93dfa93e41fab7161d 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 89fc74654ca74ecce49971da40d466ad1644ccac..ff470051e54ebcd5b1ca225c939a9e4ad03c7cce 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 d3063ca4a6fcb890186e3fcd152ac63fc1a3cb40..635ffdc4b712e93f1944a438f18c7543c6a6f2c2 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 cc536d714313e8d3fd33733251f65d7b89c0ec73..f361550c1e29eb3bbd07cec4d4ec39223642657f 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 3c32a5fc54559c011ea9d77fb2ab42a261bb5d36..e9750cfb94f2489c64d672e87be7305b6cce01df 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 d870473d5a92acd36bcdd71d5a11e6ef691abf9a..646c460bdbb69d2553b56663d6770f35ddc0e475 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 ad016df93319906f677eddc5490f3ad503452cc8..b11c9dcf1a2922ffad892eb39ec68f852475ddd4 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 f8c482e9825110d6b83b91bbbc5b35ae32eceab5..d59579d78c8e5ae52c8de5036b17e1c0fbdb7d86 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 0000000000000000000000000000000000000000..976022aa2249a470b5e385488cbea7d3d5483849 --- /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 c52fe2c830c800a4e2126be2fb4f9859ae21692d..fc12cb0c3620a5b5235409a9dda1d185513b56dc 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 3ba8f64e2664bbd9570f28df6699838e01ef8379..4fc300792bb6f01e282a68d8b4be7be7c1883680 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 (); }