From f541f70d0ecbb9fd80bea9909c1783b92d46d695 Mon Sep 17 00:00:00 2001 From: Explorer09 Date: Wed, 11 Oct 2023 03:37:39 +0800 Subject: [PATCH 1/2] Add configure check for nonnull attribute The main reason I do this is to document the minimum compiler version (GCC 3.3) for the attribute. But it may work with other compilers, too. Signed-off-by: Kang-Che Sung --- Macros.h | 14 ++++++++++++-- configure.ac | 16 ++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/Macros.h b/Macros.h index 054e7d3b7..db411e93d 100644 --- a/Macros.h +++ b/Macros.h @@ -42,7 +42,6 @@ in the source distribution for its full text. #ifdef __GNUC__ // defined by GCC and Clang #define ATTR_FORMAT(type, index, check) __attribute__((format (type, index, check))) -#define ATTR_NONNULL __attribute__((nonnull)) #define ATTR_NORETURN __attribute__((noreturn)) #define ATTR_UNUSED __attribute__((unused)) #define ATTR_MALLOC __attribute__((malloc)) @@ -50,13 +49,24 @@ in the source distribution for its full text. #else /* __GNUC__ */ #define ATTR_FORMAT(type, index, check) -#define ATTR_NONNULL #define ATTR_NORETURN #define ATTR_UNUSED #define ATTR_MALLOC #endif /* __GNUC__ */ +#ifdef HAVE_ATTR_NONNULL + +#define ATTR_NONNULL __attribute__((nonnull)) +#define ATTR_NONNULL_N(...) __attribute__((nonnull(__VA_ARGS__))) + +#else + +#define ATTR_NONNULL +#define ATTR_NONNULL_N(...) + +#endif /* HAVE_ATTR_NONNULL */ + #ifdef HAVE_ATTR_ALLOC_SIZE #define ATTR_ALLOC_SIZE1(a) __attribute__((alloc_size (a))) diff --git a/configure.ac b/configure.ac index 16d1fb9ab..c922b30ad 100644 --- a/configure.ac +++ b/configure.ac @@ -202,6 +202,22 @@ AC_COMPILE_IFELSE([ AC_MSG_RESULT(no)) CFLAGS="$old_CFLAGS" +AC_MSG_CHECKING(for nonnull) +old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Wno-error -Werror=attributes" +AC_COMPILE_IFELSE([ + AC_LANG_SOURCE( + [[ + /* Attribute supported in GCC 3.3 or later */ + __attribute__((nonnull)) int my_strcmp(const char* a, const char* b); + __attribute__((nonnull(1))) long my_strtol(const char* str, char** endptr, int base); + ]] + )], + AC_DEFINE([HAVE_ATTR_NONNULL], 1, [The nonnull attribute is supported.]) + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no)) +CFLAGS="$old_CFLAGS" + AC_MSG_CHECKING(for NaN support) dnl Note: AC_RUN_IFELSE does not try compiling the program at all when dnl $cross_compiling is 'yes'. From 5736fba7110b460fa0775c008b959467c45e38e0 Mon Sep 17 00:00:00 2001 From: Explorer09 Date: Tue, 10 Oct 2023 11:21:59 +0800 Subject: [PATCH 2/2] Add ATTR_NONNULL to various String_* functions Note: For xSnprintf function the nonnull attribute is not needed. (The `buf` argument may be NULL as long as `len` is 0, and `fmt` is implied by the "format" attribute.) Signed-off-by: Kang-Che Sung --- XUtils.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/XUtils.h b/XUtils.h index 7526df3eb..cfb375cc9 100644 --- a/XUtils.h +++ b/XUtils.h @@ -36,26 +36,33 @@ void* xReallocArrayZero(void* ptr, size_t prevmemb, size_t newmemb, size_t size) * String_startsWith gives better performance if strlen(match) can be computed * at compile time (e.g. when they are immutable string literals). :) */ +ATTR_NONNULL static inline bool String_startsWith(const char* s, const char* match) { return strncmp(s, match, strlen(match)) == 0; } bool String_contains_i(const char* s1, const char* s2, bool multi); +ATTR_NONNULL static inline bool String_eq(const char* s1, const char* s2) { return strcmp(s1, s2) == 0; } +ATTR_NONNULL char* String_cat(const char* s1, const char* s2) ATTR_MALLOC; +ATTR_NONNULL char* String_trim(const char* in) ATTR_MALLOC; +ATTR_NONNULL_N(1) char** String_split(const char* s, char sep, size_t* n); void String_freeArray(char** s); +ATTR_NONNULL char* String_readLine(FILE* fd) ATTR_MALLOC; +ATTR_NONNULL static inline char* String_strchrnul(const char* s, int c) { #ifdef HAVE_STRCHRNUL return strchrnul(s, c); @@ -73,6 +80,7 @@ ATTR_ACCESS3_R(2, 3) size_t String_safeStrncpy(char* restrict dest, const char* restrict src, size_t size); ATTR_FORMAT(printf, 2, 3) +ATTR_NONNULL_N(1, 2) int xAsprintf(char** strp, const char* fmt, ...); ATTR_FORMAT(printf, 3, 4)