]> arthur.barton.de Git - netdata.git/commitdiff
use autoconf for checking gcc function attributes
authorCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Sat, 7 Jan 2017 17:54:48 +0000 (19:54 +0200)
committerCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Sat, 7 Jan 2017 17:54:48 +0000 (19:54 +0200)
configure.ac
m4/ax_c_mallinfo.m4 [changed mode: 0755->0644]
m4/ax_c_mallopt.m4 [changed mode: 0755->0644]
m4/ax_gcc_func_attribute.m4 [new file with mode: 0644]
src/avl.h
src/common.h
src/log.h
src/main.h
src/registry_person.h
src/registry_url.h
src/web_buffer.h

index d2745f62fc48319e123508ed188dc04cd5ba3436..872427944e1acdc8ef587921948211d7cca42b31 100644 (file)
@@ -24,6 +24,12 @@ PACKAGE_RPM_VERSION="VERSION_NUMBER"
 AC_SUBST([PACKAGE_RPM_VERSION])
 AC_SUBST([PACKAGE_RPM_RELEASE])
 
+AX_GCC_FUNC_ATTRIBUTE(returns_nonnull)
+AX_GCC_FUNC_ATTRIBUTE(malloc)
+AX_GCC_FUNC_ATTRIBUTE(noreturn)
+AX_GCC_FUNC_ATTRIBUTE(format)
+AX_GCC_FUNC_ATTRIBUTE(warn_unused_result)
+
 AC_CONFIG_AUX_DIR([.])
 AC_CONFIG_HEADERS([config.h])
 AC_CONFIG_MACRO_DIR([m4])
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
diff --git a/m4/ax_gcc_func_attribute.m4 b/m4/ax_gcc_func_attribute.m4
new file mode 100644 (file)
index 0000000..a6d9f6c
--- /dev/null
@@ -0,0 +1,226 @@
+# ===========================================================================
+#   http://www.gnu.org/software/autoconf-archive/ax_gcc_func_attribute.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_GCC_FUNC_ATTRIBUTE(ATTRIBUTE)
+#
+# DESCRIPTION
+#
+#   This macro checks if the compiler supports one of GCC's function
+#   attributes; many other compilers also provide function attributes with
+#   the same syntax. Compiler warnings are used to detect supported
+#   attributes as unsupported ones are ignored by default so quieting
+#   warnings when using this macro will yield false positives.
+#
+#   The ATTRIBUTE parameter holds the name of the attribute to be checked.
+#
+#   If ATTRIBUTE is supported define HAVE_FUNC_ATTRIBUTE_<ATTRIBUTE>.
+#
+#   The macro caches its result in the ax_cv_have_func_attribute_<attribute>
+#   variable.
+#
+#   The macro currently supports the following function attributes:
+#
+#    alias
+#    aligned
+#    alloc_size
+#    always_inline
+#    artificial
+#    cold
+#    const
+#    constructor
+#    constructor_priority for constructor attribute with priority
+#    deprecated
+#    destructor
+#    dllexport
+#    dllimport
+#    error
+#    externally_visible
+#    flatten
+#    format
+#    format_arg
+#    gnu_inline
+#    hot
+#    ifunc
+#    leaf
+#    malloc
+#    noclone
+#    noinline
+#    nonnull
+#    noreturn
+#    nothrow
+#    optimize
+#    pure
+#    unused
+#    used
+#    visibility
+#    warning
+#    warn_unused_result
+#    weak
+#    weakref
+#
+#   Unsuppored function attributes will be tested with a prototype returning
+#   an int and not accepting any arguments and the result of the check might
+#   be wrong or meaningless so use with care.
+#
+# LICENSE
+#
+#   Copyright (c) 2013 Gabriele Svelto <gabriele.svelto@gmail.com>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved.  This file is offered as-is, without any
+#   warranty.
+
+#serial 4
+
+AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [
+    AS_VAR_PUSHDEF([ac_var], [ax_cv_have_func_attribute_$1])
+
+    AC_CACHE_CHECK([for __attribute__(($1))], [ac_var], [
+        AC_LINK_IFELSE([AC_LANG_PROGRAM([
+            m4_case([$1],
+                [alias], [
+                    int foo( void ) { return 0; }
+                    int bar( void ) __attribute__(($1("foo")));
+                ],
+                [aligned], [
+                    int foo( void ) __attribute__(($1(32)));
+                ],
+                [alloc_size], [
+                    void *foo(int a) __attribute__(($1(1)));
+                ],
+                [always_inline], [
+                    inline __attribute__(($1)) int foo( void ) { return 0; }
+                ],
+                [artificial], [
+                    inline __attribute__(($1)) int foo( void ) { return 0; }
+                ],
+                [cold], [
+                    int foo( void ) __attribute__(($1));
+                ],
+                [const], [
+                    int foo( void ) __attribute__(($1));
+                ],
+                [constructor_priority], [
+                    int foo( void ) __attribute__((__constructor__(65535/2)));
+                ],
+                [constructor], [
+                    int foo( void ) __attribute__(($1));
+                ],
+                [deprecated], [
+                    int foo( void ) __attribute__(($1("")));
+                ],
+                [destructor], [
+                    int foo( void ) __attribute__(($1));
+                ],
+                [dllexport], [
+                    __attribute__(($1)) int foo( void ) { return 0; }
+                ],
+                [dllimport], [
+                    int foo( void ) __attribute__(($1));
+                ],
+                [error], [
+                    int foo( void ) __attribute__(($1("")));
+                ],
+                [externally_visible], [
+                    int foo( void ) __attribute__(($1));
+                ],
+                [flatten], [
+                    int foo( void ) __attribute__(($1));
+                ],
+                [format], [
+                    int foo(const char *p, ...) __attribute__(($1(printf, 1, 2)));
+                ],
+                [format_arg], [
+                    char *foo(const char *p) __attribute__(($1(1)));
+                ],
+                [gnu_inline], [
+                    inline __attribute__(($1)) int foo( void ) { return 0; }
+                ],
+                [hot], [
+                    int foo( void ) __attribute__(($1));
+                ],
+                [ifunc], [
+                    int my_foo( void ) { return 0; }
+                    static int (*resolve_foo(void))(void) { return my_foo; }
+                    int foo( void ) __attribute__(($1("resolve_foo")));
+                ],
+                [leaf], [
+                    __attribute__(($1)) int foo( void ) { return 0; }
+                ],
+                [malloc], [
+                    void *foo( void ) __attribute__(($1));
+                ],
+                [noclone], [
+                    int foo( void ) __attribute__(($1));
+                ],
+                [noinline], [
+                    __attribute__(($1)) int foo( void ) { return 0; }
+                ],
+                [nonnull], [
+                    int foo(char *p) __attribute__(($1(1)));
+                ],
+                [noreturn], [
+                    void foo( void ) __attribute__(($1));
+                ],
+                [nothrow], [
+                    int foo( void ) __attribute__(($1));
+                ],
+                [optimize], [
+                    __attribute__(($1(3))) int foo( void ) { return 0; }
+                ],
+                [pure], [
+                    int foo( void ) __attribute__(($1));
+                ],
+                [returns_nonnull], [
+                    void *foo( void ) __attribute__(($1));
+                ],
+                [unused], [
+                    int foo( void ) __attribute__(($1));
+                ],
+                [used], [
+                    int foo( void ) __attribute__(($1));
+                ],
+                [visibility], [
+                    int foo_def( void ) __attribute__(($1("default")));
+                    int foo_hid( void ) __attribute__(($1("hidden")));
+                    int foo_int( void ) __attribute__(($1("internal")));
+                    int foo_pro( void ) __attribute__(($1("protected")));
+                ],
+                [warning], [
+                    int foo( void ) __attribute__(($1("")));
+                ],
+                [warn_unused_result], [
+                    int foo( void ) __attribute__(($1));
+                ],
+                [weak], [
+                    int foo( void ) __attribute__(($1));
+                ],
+                [weakref], [
+                    static int foo( void ) { return 0; }
+                    static int bar( void ) __attribute__(($1("foo")));
+                ],
+                [
+                 m4_warn([syntax], [Unsupported attribute $1, the test may fail])
+                 int foo( void ) __attribute__(($1));
+                ]
+            )], [])
+            ],
+            dnl GCC doesn't exit with an error if an unknown attribute is
+            dnl provided but only outputs a warning, so accept the attribute
+            dnl only if no warning were issued.
+            [AS_IF([test -s conftest.err],
+                [AS_VAR_SET([ac_var], [no])],
+                [AS_VAR_SET([ac_var], [yes])])],
+            [AS_VAR_SET([ac_var], [no])])
+    ])
+
+    AS_IF([test yes = AS_VAR_GET([ac_var])],
+        [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_FUNC_ATTRIBUTE_$1), 1,
+            [Define to 1 if the system has the `$1' function attribute])], [])
+
+    AS_VAR_POPDEF([ac_var])
+])
index 53ef7ecaff7d9a497828e15b92684f92d6788883..d30be0dd85cc7e5d5918b610da9f8446b08dd623 100644 (file)
--- a/src/avl.h
+++ b/src/avl.h
@@ -56,16 +56,16 @@ typedef struct avl_tree_lock {
  * a is linked directly to the tree, so it has to
  * be properly allocated by the caller.
  */
-avl *avl_insert_lock(avl_tree_lock *t, avl *a) __attribute__((returns_nonnull, warn_unused_result));
-avl *avl_insert(avl_tree *t, avl *a) __attribute__((returns_nonnull, warn_unused_result));
+avl *avl_insert_lock(avl_tree_lock *t, avl *a) NEVERNULL WARNUNUSED;
+avl *avl_insert(avl_tree *t, avl *a) NEVERNULL WARNUNUSED;
 
 /* Remove an element a from the AVL tree t
  * returns a pointer to the removed element
  * or NULL if an element equal to a is not found
  * (equal as returned by t->compar())
  */
-avl *avl_remove_lock(avl_tree_lock *t, avl *a) __attribute__((warn_unused_result));
-avl *avl_remove(avl_tree *t, avl *a) __attribute__((warn_unused_result));
+avl *avl_remove_lock(avl_tree_lock *t, avl *a) WARNUNUSED;
+avl *avl_remove(avl_tree *t, avl *a) WARNUNUSED;
 
 /* Find the element into the tree that equal to a
  * (equal as returned by t->compar())
index c4255db059e0f19669422af45ce39d7fc05e7299..48b7c311670d37eaa57b68439ff0933ab33f0432 100644 (file)
@@ -5,6 +5,9 @@
 #include <config.h>
 #endif
 
+// ----------------------------------------------------------------------------
+// system include files for all netdata C programs
+
 /* select the memory allocator, based on autoconf findings */
 #if defined(ENABLE_JEMALLOC)
 
 
 #include <pthread.h>
 #include <errno.h>
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
 #include <stddef.h>
-
 #include <ctype.h>
 #include <string.h>
 #include <strings.h>
-
 #include <arpa/inet.h>
 #include <netinet/tcp.h>
 
 #include <signal.h>
 #include <syslog.h>
 #include <sys/mman.h>
+
 #if !(defined(__FreeBSD__) || defined(__APPLE__))
 #include <sys/prctl.h>
 #endif /* __FreeBSD__ || __APPLE__*/
+
 #include <sys/resource.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <zlib.h>
 #endif
 
+// ----------------------------------------------------------------------------
+// netdata common definitions
+
 #if (SIZEOF_VOID_P == 8)
 #define ENVIRONMENT64
 #elif (SIZEOF_VOID_P == 4)
 #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
 #endif // __GNUC__
 
+#ifdef HAVE_FUNC_ATTRIBUTE_RETURNS_NONNULL
+#define NEVERNULL __attribute__((returns_nonnull))
+#else
+#define NEVERNULL
+#endif
+
+#ifdef HAVE_FUNC_ATTRIBUTE_MALLOC
+#define MALLOCLIKE __attribute__((malloc))
+#else
+#define MALLOCLIKE
+#endif
+
+#ifdef HAVE_FUNC_ATTRIBUTE_FORMAT
+#define PRINTFLIKE(f, a) __attribute__ ((format(__printf__, f, a)))
+#else
+#define PRINTFLIKE(f, a)
+#endif
+
+#ifdef HAVE_FUNC_ATTRIBUTE_NORETURN
+#define NORETURN __attribute__ ((noreturn))
+#else
+#define NORETURN
+#endif
+
+#ifdef HAVE_FUNC_ATTRIBUTE_WARN_UNUSED_RESULT
+#define WARNUNUSED __attribute__ ((warn_unused_result))
+#else
+#define WARNUNUSED
+#endif
+
+#ifdef abs
+#undef abs
+#endif
+#define abs(x) ((x < 0)? -x : x)
+
+#define GUID_LEN 36
+
+// ----------------------------------------------------------------------------
+// netdata include files
+
 #include "avl.h"
 #include "clocks.h"
 #include "log.h"
 #include "plugin_checks.h"
 #include "plugin_idlejitter.h"
 #include "plugin_nfacct.h"
+
 #if defined(__FreeBSD__)
 #include "plugin_freebsd.h"
 #elif defined(__APPLE__)
 #else
 #include "plugin_proc.h"
 #endif /* __FreeBSD__, __APPLE__*/
+
 #include "plugin_tc.h"
 #include "plugins_d.h"
-
 #include "socket.h"
-
 #include "eval.h"
 #include "health.h"
-
 #include "rrd.h"
 #include "rrd2json.h"
-
 #include "web_client.h"
 #include "web_server.h"
-
 #include "registry.h"
 #include "daemon.h"
 #include "main.h"
 #include "unit_test.h"
-
 #include "ipc.h"
 #include "backends.h"
 
-#ifdef abs
-#undef abs
-#endif
-#define abs(x) ((x < 0)? -x : x)
-
-#define GUID_LEN 36
-
 extern void netdata_fix_chart_id(char *s);
 extern void netdata_fix_chart_name(char *s);
 
@@ -184,7 +218,7 @@ extern char *trim(char *s);
 
 extern char *strncpyz(char *dst, const char *src, size_t n);
 extern int  vsnprintfz(char *dst, size_t n, const char *fmt, va_list args);
-extern int  snprintfz(char *dst, size_t n, const char *fmt, ...) __attribute__ (( format (printf, 3, 4)));
+extern int  snprintfz(char *dst, size_t n, const char *fmt, ...) PRINTFLIKE(3, 4);
 
 // memory allocation functions that handle failures
 #ifdef NETDATA_LOG_ALLOCATIONS
@@ -200,10 +234,10 @@ extern void *mallocz_int(const char *file, const char *function, const unsigned
 extern void *reallocz_int(const char *file, const char *function, const unsigned long line, void *ptr, size_t size);
 extern void freez_int(const char *file, const char *function, const unsigned long line, void *ptr);
 #else
-extern char *strdupz(const char *s) __attribute__((returns_nonnull, malloc));
-extern void *callocz(size_t nmemb, size_t size) __attribute__((returns_nonnull, malloc));
-extern void *mallocz(size_t size) __attribute__((returns_nonnull, malloc));
-extern void *reallocz(void *ptr, size_t size) __attribute__((returns_nonnull, malloc));
+extern char *strdupz(const char *s) MALLOCLIKE NEVERNULL;
+extern void *callocz(size_t nmemb, size_t size) MALLOCLIKE NEVERNULL;
+extern void *mallocz(size_t size) MALLOCLIKE NEVERNULL;
+extern void *reallocz(void *ptr, size_t size) MALLOCLIKE NEVERNULL;
 extern void freez(void *ptr);
 #endif
 
index 92ffe6f1edcb8c9b92d571ae7d0ef0e863934834..e61ffdd08ab596b2cc77d9638f7952a66d10abd1 100644 (file)
--- a/src/log.h
+++ b/src/log.h
@@ -64,10 +64,10 @@ extern void reopen_all_log_files();
 #define fatal(args...)   fatal_int(__FILE__, __FUNCTION__, __LINE__, ##args)
 
 extern void log_date(FILE *out);
-extern void debug_int( const char *file, const char *function, const unsigned long line, const char *fmt, ... ) __attribute__ (( format (printf, 4, 5)));
-extern void info_int( const char *file, const char *function, const unsigned long line, const char *fmt, ... ) __attribute__ (( format (printf, 4, 5)));
-extern void error_int( const char *prefix, const char *file, const char *function, const unsigned long line, const char *fmt, ... ) __attribute__ (( format (printf, 5, 6)));
-extern void fatal_int( const char *file, const char *function, const unsigned long line, const char *fmt, ... ) __attribute__ ((noreturn, format (printf, 4, 5)));
-extern void log_access( const char *fmt, ... ) __attribute__ (( format (printf, 1, 2)));
+extern void debug_int( const char *file, const char *function, const unsigned long line, const char *fmt, ... ) PRINTFLIKE(4, 5);
+extern void info_int( const char *file, const char *function, const unsigned long line, const char *fmt, ... ) PRINTFLIKE(4, 5);
+extern void error_int( const char *prefix, const char *file, const char *function, const unsigned long line, const char *fmt, ... ) PRINTFLIKE(5, 6);
+extern void fatal_int( const char *file, const char *function, const unsigned long line, const char *fmt, ... ) NORETURN PRINTFLIKE(4, 5);
+extern void log_access( const char *fmt, ... ) PRINTFLIKE(1, 2);
 
 #endif /* NETDATA_LOG_H */
index 646827fbd919de42422a70e0869d5eb19f823a34..be2d1c677b9ead4da24936b27e91b9758c6be758 100644 (file)
@@ -26,6 +26,6 @@ extern struct option_def options[];
 
 extern void kill_childs(void);
 extern int killpid(pid_t pid, int signal);
-extern void netdata_cleanup_and_exit(int ret) __attribute__ ((noreturn));
+extern void netdata_cleanup_and_exit(int ret) NORETURN;
 
 #endif /* NETDATA_MAIN_H */
index 73c9f11c417453b9c234869b2d00c151f947b1a7..5f6cc24435a7aa1a96adb22a443268c414cddfed 100644 (file)
@@ -41,8 +41,8 @@ typedef struct registry_person REGISTRY_PERSON;
 
 // PERSON_URL
 extern REGISTRY_PERSON_URL *registry_person_url_index_find(REGISTRY_PERSON *p, const char *url);
-extern REGISTRY_PERSON_URL *registry_person_url_index_add(REGISTRY_PERSON *p, REGISTRY_PERSON_URL *pu) __attribute__((returns_nonnull, warn_unused_result));
-extern REGISTRY_PERSON_URL *registry_person_url_index_del(REGISTRY_PERSON *p, REGISTRY_PERSON_URL *pu) __attribute__((warn_unused_result));
+extern REGISTRY_PERSON_URL *registry_person_url_index_add(REGISTRY_PERSON *p, REGISTRY_PERSON_URL *pu) NEVERNULL WARNUNUSED;
+extern REGISTRY_PERSON_URL *registry_person_url_index_del(REGISTRY_PERSON *p, REGISTRY_PERSON_URL *pu) WARNUNUSED;
 
 extern REGISTRY_PERSON_URL *registry_person_url_allocate(REGISTRY_PERSON *p, REGISTRY_MACHINE *m, REGISTRY_URL *u, char *name, size_t namelen, time_t when);
 extern REGISTRY_PERSON_URL *registry_person_url_reallocate(REGISTRY_PERSON *p, REGISTRY_MACHINE *m, REGISTRY_URL *u, char *name, size_t namelen, time_t when, REGISTRY_PERSON_URL *pu);
index 50bd2497e220961131986975fead9e7dc82cac13..5ac52f5a5512cf24c08386aa8779ccf98844d35c 100644 (file)
@@ -22,11 +22,11 @@ typedef struct registry_url REGISTRY_URL;
 
 // REGISTRY_URL INDEX
 extern int registry_url_compare(void *a, void *b);
-extern REGISTRY_URL *registry_url_index_del(REGISTRY_URL *u) __attribute__((warn_unused_result));
-extern REGISTRY_URL *registry_url_index_add(REGISTRY_URL *u) __attribute__((returns_nonnull, warn_unused_result));
+extern REGISTRY_URL *registry_url_index_del(REGISTRY_URL *u) WARNUNUSED;
+extern REGISTRY_URL *registry_url_index_add(REGISTRY_URL *u) NEVERNULL WARNUNUSED;
 
 // REGISTRY_URL MANAGEMENT
-extern REGISTRY_URL *registry_url_get(const char *url, size_t urllen) __attribute__((returns_nonnull));
+extern REGISTRY_URL *registry_url_get(const char *url, size_t urllen) NEVERNULL;
 extern void registry_url_link(REGISTRY_URL *u);
 extern void registry_url_unlink(REGISTRY_URL *u);
 
index 14d16f3f60e1383d4461fc5d31a5650f4361d71b..8f0d29cd22546e82cfab46463cce773013f271a2 100644 (file)
@@ -62,9 +62,9 @@ extern BUFFER *buffer_create(size_t size);
 extern void buffer_free(BUFFER *b);
 extern void buffer_increase(BUFFER *b, size_t free_size_required);
 
-extern void buffer_snprintf(BUFFER *wb, size_t len, const char *fmt, ...) __attribute__ (( format (printf, 3, 4)));
+extern void buffer_snprintf(BUFFER *wb, size_t len, const char *fmt, ...) PRINTFLIKE(3, 4);
 extern void buffer_vsprintf(BUFFER *wb, const char *fmt, va_list args);
-extern void buffer_sprintf(BUFFER *wb, const char *fmt, ...) __attribute__ (( format (printf, 2, 3)));
+extern void buffer_sprintf(BUFFER *wb, const char *fmt, ...) PRINTFLIKE(2,3);
 extern void buffer_strcat_htmlescape(BUFFER *wb, const char *txt);
 
 extern void buffer_char_replace(BUFFER *wb, char from, char to);