use autoconf for checking gcc function attributes
Costa Tsaousis (ktsaou) committed
Jan 7, 2017 at 19:54 UTC
cea19eee0c125d817858d185c7b5e4e6f4235f08
11 files changed
+304
-38
configure.ac
+6
@@ -24,6 +24,12 @@ PACKAGE_RPM_VERSION="VERSION_NUMBER"
24
AC_SUBST([PACKAGE_RPM_VERSION])
25
AC_SUBST([PACKAGE_RPM_RELEASE])
26
27
+AX_GCC_FUNC_ATTRIBUTE(returns_nonnull)
28
+AX_GCC_FUNC_ATTRIBUTE(malloc)
29
+AX_GCC_FUNC_ATTRIBUTE(noreturn)
30
+AX_GCC_FUNC_ATTRIBUTE(format)
31
+AX_GCC_FUNC_ATTRIBUTE(warn_unused_result)
32
+
33
AC_CONFIG_AUX_DIR([.])
34
AC_CONFIG_HEADERS([config.h])
35
AC_CONFIG_MACRO_DIR([m4])
m4/ax_c_mallinfo.m4
m4/ax_c_mallopt.m4
m4/ax_gcc_func_attribute.m4
new
+226
@@ -0,0 +1,226 @@
1
+# ===========================================================================
2
+# http://www.gnu.org/software/autoconf-archive/ax_gcc_func_attribute.html
3
+# ===========================================================================
4
+#
5
+# SYNOPSIS
6
+#
7
+# AX_GCC_FUNC_ATTRIBUTE(ATTRIBUTE)
8
+#
9
+# DESCRIPTION
10
+#
11
+# This macro checks if the compiler supports one of GCC's function
12
+# attributes; many other compilers also provide function attributes with
13
+# the same syntax. Compiler warnings are used to detect supported
14
+# attributes as unsupported ones are ignored by default so quieting
15
+# warnings when using this macro will yield false positives.
16
+#
17
+# The ATTRIBUTE parameter holds the name of the attribute to be checked.
18
+#
19
+# If ATTRIBUTE is supported define HAVE_FUNC_ATTRIBUTE_<ATTRIBUTE>.
20
+#
21
+# The macro caches its result in the ax_cv_have_func_attribute_<attribute>
22
+# variable.
23
+#
24
+# The macro currently supports the following function attributes:
25
+#
26
+# alias
27
+# aligned
28
+# alloc_size
29
+# always_inline
30
+# artificial
31
+# cold
32
+# const
33
+# constructor
34
+# constructor_priority for constructor attribute with priority
35
+# deprecated
36
+# destructor
37
+# dllexport
38
+# dllimport
39
+# error
40
+# externally_visible
41
+# flatten
42
+# format
43
+# format_arg
44
+# gnu_inline
45
+# hot
46
+# ifunc
47
+# leaf
48
+# malloc
49
+# noclone
50
+# noinline
51
+# nonnull
52
+# noreturn
53
+# nothrow
54
+# optimize
55
+# pure
56
+# unused
57
+# used
58
+# visibility
59
+# warning
60
+# warn_unused_result
61
+# weak
62
+# weakref
63
+#
64
+# Unsuppored function attributes will be tested with a prototype returning
65
+# an int and not accepting any arguments and the result of the check might
66
+# be wrong or meaningless so use with care.
67
+#
68
+# LICENSE
69
+#
70
+# Copyright (c) 2013 Gabriele Svelto <gabriele.svelto@gmail.com>
71
+#
72
+# Copying and distribution of this file, with or without modification, are
73
+# permitted in any medium without royalty provided the copyright notice
74
+# and this notice are preserved. This file is offered as-is, without any
75
+# warranty.
76
+
77
+#serial 4
78
+
79
+AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [
80
+ AS_VAR_PUSHDEF([ac_var], [ax_cv_have_func_attribute_$1])
81
+
82
+ AC_CACHE_CHECK([for __attribute__(($1))], [ac_var], [
83
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([
84
+ m4_case([$1],
85
+ [alias], [
86
+ int foo( void ) { return 0; }
87
+ int bar( void ) __attribute__(($1("foo")));
88
+ ],
89
+ [aligned], [
90
+ int foo( void ) __attribute__(($1(32)));
91
+ ],
92
+ [alloc_size], [
93
+ void *foo(int a) __attribute__(($1(1)));
94
+ ],
95
+ [always_inline], [
96
+ inline __attribute__(($1)) int foo( void ) { return 0; }
97
+ ],
98
+ [artificial], [
99
+ inline __attribute__(($1)) int foo( void ) { return 0; }
100
+ ],
101
+ [cold], [
102
+ int foo( void ) __attribute__(($1));
103
+ ],
104
+ [const], [
105
+ int foo( void ) __attribute__(($1));
106
+ ],
107
+ [constructor_priority], [
108
+ int foo( void ) __attribute__((__constructor__(65535/2)));
109
+ ],
110
+ [constructor], [
111
+ int foo( void ) __attribute__(($1));
112
+ ],
113
+ [deprecated], [
114
+ int foo( void ) __attribute__(($1("")));
115
+ ],
116
+ [destructor], [
117
+ int foo( void ) __attribute__(($1));
118
+ ],
119
+ [dllexport], [
120
+ __attribute__(($1)) int foo( void ) { return 0; }
121
+ ],
122
+ [dllimport], [
123
+ int foo( void ) __attribute__(($1));
124
+ ],
125
+ [error], [
126
+ int foo( void ) __attribute__(($1("")));
127
+ ],
128
+ [externally_visible], [
129
+ int foo( void ) __attribute__(($1));
130
+ ],
131
+ [flatten], [
132
+ int foo( void ) __attribute__(($1));
133
+ ],
134
+ [format], [
135
+ int foo(const char *p, ...) __attribute__(($1(printf, 1, 2)));
136
+ ],
137
+ [format_arg], [
138
+ char *foo(const char *p) __attribute__(($1(1)));
139
+ ],
140
+ [gnu_inline], [
141
+ inline __attribute__(($1)) int foo( void ) { return 0; }
142
+ ],
143
+ [hot], [
144
+ int foo( void ) __attribute__(($1));
145
+ ],
146
+ [ifunc], [
147
+ int my_foo( void ) { return 0; }
148
+ static int (*resolve_foo(void))(void) { return my_foo; }
149
+ int foo( void ) __attribute__(($1("resolve_foo")));
150
+ ],
151
+ [leaf], [
152
+ __attribute__(($1)) int foo( void ) { return 0; }
153
+ ],
154
+ [malloc], [
155
+ void *foo( void ) __attribute__(($1));
156
+ ],
157
+ [noclone], [
158
+ int foo( void ) __attribute__(($1));
159
+ ],
160
+ [noinline], [
161
+ __attribute__(($1)) int foo( void ) { return 0; }
162
+ ],
163
+ [nonnull], [
164
+ int foo(char *p) __attribute__(($1(1)));
165
+ ],
166
+ [noreturn], [
167
+ void foo( void ) __attribute__(($1));
168
+ ],
169
+ [nothrow], [
170
+ int foo( void ) __attribute__(($1));
171
+ ],
172
+ [optimize], [
173
+ __attribute__(($1(3))) int foo( void ) { return 0; }
174
+ ],
175
+ [pure], [
176
+ int foo( void ) __attribute__(($1));
177
+ ],
178
+ [returns_nonnull], [
179
+ void *foo( void ) __attribute__(($1));
180
+ ],
181
+ [unused], [
182
+ int foo( void ) __attribute__(($1));
183
+ ],
184
+ [used], [
185
+ int foo( void ) __attribute__(($1));
186
+ ],
187
+ [visibility], [
188
+ int foo_def( void ) __attribute__(($1("default")));
189
+ int foo_hid( void ) __attribute__(($1("hidden")));
190
+ int foo_int( void ) __attribute__(($1("internal")));
191
+ int foo_pro( void ) __attribute__(($1("protected")));
192
+ ],
193
+ [warning], [
194
+ int foo( void ) __attribute__(($1("")));
195
+ ],
196
+ [warn_unused_result], [
197
+ int foo( void ) __attribute__(($1));
198
+ ],
199
+ [weak], [
200
+ int foo( void ) __attribute__(($1));
201
+ ],
202
+ [weakref], [
203
+ static int foo( void ) { return 0; }
204
+ static int bar( void ) __attribute__(($1("foo")));
205
+ ],
206
+ [
207
+ m4_warn([syntax], [Unsupported attribute $1, the test may fail])
208
+ int foo( void ) __attribute__(($1));
209
+ ]
210
+ )], [])
211
+ ],
212
+ dnl GCC doesn't exit with an error if an unknown attribute is
213
+ dnl provided but only outputs a warning, so accept the attribute
214
+ dnl only if no warning were issued.
215
+ [AS_IF([test -s conftest.err],
216
+ [AS_VAR_SET([ac_var], [no])],
217
+ [AS_VAR_SET([ac_var], [yes])])],
218
+ [AS_VAR_SET([ac_var], [no])])
219
+ ])
220
+
221
+ AS_IF([test yes = AS_VAR_GET([ac_var])],
222
+ [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_FUNC_ATTRIBUTE_$1), 1,
223
+ [Define to 1 if the system has the `$1' function attribute])], [])
224
+
225
+ AS_VAR_POPDEF([ac_var])
226
+])
src/avl.h
+4
-4
@@ -56,16 +56,16 @@ typedef struct avl_tree_lock {
56
* a is linked directly to the tree, so it has to
57
* be properly allocated by the caller.
58
*/
59
-avl *avl_insert_lock(avl_tree_lock *t, avl *a) __attribute__((returns_nonnull, warn_unused_result));
60
-avl *avl_insert(avl_tree *t, avl *a) __attribute__((returns_nonnull, warn_unused_result));
59
+avl *avl_insert_lock(avl_tree_lock *t, avl *a) NEVERNULL WARNUNUSED;
60
+avl *avl_insert(avl_tree *t, avl *a) NEVERNULL WARNUNUSED;
61
62
/* Remove an element a from the AVL tree t
63
* returns a pointer to the removed element
64
* or NULL if an element equal to a is not found
65
* (equal as returned by t->compar())
66
*/
67
-avl *avl_remove_lock(avl_tree_lock *t, avl *a) __attribute__((warn_unused_result));
68
-avl *avl_remove(avl_tree *t, avl *a) __attribute__((warn_unused_result));
67
+avl *avl_remove_lock(avl_tree_lock *t, avl *a) WARNUNUSED;
68
+avl *avl_remove(avl_tree *t, avl *a) WARNUNUSED;
69
70
/* Find the element into the tree that equal to a
71
* (equal as returned by t->compar())
src/common.h
+55
-21
@@ -5,6 +5,9 @@
5
#include <config.h>
6
#endif
7
8
+// ----------------------------------------------------------------------------
9
+// system include files for all netdata C programs
10
+
11
/* select the memory allocator, based on autoconf findings */
12
#if defined(ENABLE_JEMALLOC)
13
@@ -28,16 +31,13 @@
31
32
#include <pthread.h>
33
#include <errno.h>
31
-
34
#include <stdio.h>
35
#include <stdlib.h>
36
#include <stdarg.h>
37
#include <stddef.h>
36
-
38
#include <ctype.h>
39
#include <string.h>
40
#include <strings.h>
40
-
41
#include <arpa/inet.h>
42
#include <netinet/tcp.h>
43
@@ -66,9 +66,11 @@
66
#include <signal.h>
67
#include <syslog.h>
68
#include <sys/mman.h>
69
+
70
#if !(defined(__FreeBSD__) || defined(__APPLE__))
71
#include <sys/prctl.h>
72
#endif /* __FreeBSD__ || __APPLE__*/
73
+
74
#include <sys/resource.h>
75
#include <sys/socket.h>
76
#include <sys/stat.h>
@@ -107,6 +109,9 @@
109
#include <zlib.h>
110
#endif
111
112
+// ----------------------------------------------------------------------------
113
+// netdata common definitions
114
+
115
#if (SIZEOF_VOID_P == 8)
116
#define ENVIRONMENT64
117
#elif (SIZEOF_VOID_P == 4)
@@ -119,6 +124,46 @@
124
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
125
#endif // __GNUC__
126
127
+#ifdef HAVE_FUNC_ATTRIBUTE_RETURNS_NONNULL
128
+#define NEVERNULL __attribute__((returns_nonnull))
129
+#else
130
+#define NEVERNULL
131
+#endif
132
+
133
+#ifdef HAVE_FUNC_ATTRIBUTE_MALLOC
134
+#define MALLOCLIKE __attribute__((malloc))
135
+#else
136
+#define MALLOCLIKE
137
+#endif
138
+
139
+#ifdef HAVE_FUNC_ATTRIBUTE_FORMAT
140
+#define PRINTFLIKE(f, a) __attribute__ ((format(__printf__, f, a)))
141
+#else
142
+#define PRINTFLIKE(f, a)
143
+#endif
144
+
145
+#ifdef HAVE_FUNC_ATTRIBUTE_NORETURN
146
+#define NORETURN __attribute__ ((noreturn))
147
+#else
148
+#define NORETURN
149
+#endif
150
+
151
+#ifdef HAVE_FUNC_ATTRIBUTE_WARN_UNUSED_RESULT
152
+#define WARNUNUSED __attribute__ ((warn_unused_result))
153
+#else
154
+#define WARNUNUSED
155
+#endif
156
+
157
+#ifdef abs
158
+#undef abs
159
+#endif
160
+#define abs(x) ((x < 0)? -x : x)
161
+
162
+#define GUID_LEN 36
163
+
164
+// ----------------------------------------------------------------------------
165
+// netdata include files
166
+
167
#include "avl.h"
168
#include "clocks.h"
169
#include "log.h"
@@ -136,6 +181,7 @@
181
#include "plugin_checks.h"
182
#include "plugin_idlejitter.h"
183
#include "plugin_nfacct.h"
184
+
185
#if defined(__FreeBSD__)
186
#include "plugin_freebsd.h"
187
#elif defined(__APPLE__)
@@ -143,35 +189,23 @@
189
#else
190
#include "plugin_proc.h"
191
#endif /* __FreeBSD__, __APPLE__*/
192
+
193
#include "plugin_tc.h"
194
#include "plugins_d.h"
148
-
195
#include "socket.h"
150
-
196
#include "eval.h"
197
#include "health.h"
153
-
198
#include "rrd.h"
199
#include "rrd2json.h"
156
-
200
#include "web_client.h"
201
#include "web_server.h"
159
-
202
#include "registry.h"
203
#include "daemon.h"
204
#include "main.h"
205
#include "unit_test.h"
164
-
206
#include "ipc.h"
207
#include "backends.h"
208
168
-#ifdef abs
169
-#undef abs
170
-#endif
171
-#define abs(x) ((x < 0)? -x : x)
172
-
173
-#define GUID_LEN 36
174
-
209
extern void netdata_fix_chart_id(char *s);
210
extern void netdata_fix_chart_name(char *s);
211
@@ -184,7 +218,7 @@ extern char *trim(char *s);
218
219
extern char *strncpyz(char *dst, const char *src, size_t n);
220
extern int vsnprintfz(char *dst, size_t n, const char *fmt, va_list args);
187
-extern int snprintfz(char *dst, size_t n, const char *fmt, ...) __attribute__ (( format (printf, 3, 4)));
221
+extern int snprintfz(char *dst, size_t n, const char *fmt, ...) PRINTFLIKE(3, 4);
222
223
// memory allocation functions that handle failures
224
#ifdef NETDATA_LOG_ALLOCATIONS
@@ -200,10 +234,10 @@ extern void *mallocz_int(const char *file, const char *function, const unsigned
234
extern void *reallocz_int(const char *file, const char *function, const unsigned long line, void *ptr, size_t size);
235
extern void freez_int(const char *file, const char *function, const unsigned long line, void *ptr);
236
#else
203
-extern char *strdupz(const char *s) __attribute__((returns_nonnull, malloc));
204
-extern void *callocz(size_t nmemb, size_t size) __attribute__((returns_nonnull, malloc));
205
-extern void *mallocz(size_t size) __attribute__((returns_nonnull, malloc));
206
-extern void *reallocz(void *ptr, size_t size) __attribute__((returns_nonnull, malloc));
237
+extern char *strdupz(const char *s) MALLOCLIKE NEVERNULL;
238
+extern void *callocz(size_t nmemb, size_t size) MALLOCLIKE NEVERNULL;
239
+extern void *mallocz(size_t size) MALLOCLIKE NEVERNULL;
240
+extern void *reallocz(void *ptr, size_t size) MALLOCLIKE NEVERNULL;
241
extern void freez(void *ptr);
242
#endif
243
src/log.h
+5
-5
@@ -64,10 +64,10 @@ extern void reopen_all_log_files();
64
#define fatal(args...) fatal_int(__FILE__, __FUNCTION__, __LINE__, ##args)
65
66
extern void log_date(FILE *out);
67
-extern void debug_int( const char *file, const char *function, const unsigned long line, const char *fmt, ... ) __attribute__ (( format (printf, 4, 5)));
68
-extern void info_int( const char *file, const char *function, const unsigned long line, const char *fmt, ... ) __attribute__ (( format (printf, 4, 5)));
69
-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)));
70
-extern void fatal_int( const char *file, const char *function, const unsigned long line, const char *fmt, ... ) __attribute__ ((noreturn, format (printf, 4, 5)));
71
-extern void log_access( const char *fmt, ... ) __attribute__ (( format (printf, 1, 2)));
67
+extern void debug_int( const char *file, const char *function, const unsigned long line, const char *fmt, ... ) PRINTFLIKE(4, 5);
68
+extern void info_int( const char *file, const char *function, const unsigned long line, const char *fmt, ... ) PRINTFLIKE(4, 5);
69
+extern void error_int( const char *prefix, const char *file, const char *function, const unsigned long line, const char *fmt, ... ) PRINTFLIKE(5, 6);
70
+extern void fatal_int( const char *file, const char *function, const unsigned long line, const char *fmt, ... ) NORETURN PRINTFLIKE(4, 5);
71
+extern void log_access( const char *fmt, ... ) PRINTFLIKE(1, 2);
72
73
#endif /* NETDATA_LOG_H */
src/main.h
+1
-1
@@ -26,6 +26,6 @@ extern struct option_def options[];
26
27
extern void kill_childs(void);
28
extern int killpid(pid_t pid, int signal);
29
-extern void netdata_cleanup_and_exit(int ret) __attribute__ ((noreturn));
29
+extern void netdata_cleanup_and_exit(int ret) NORETURN;
30
31
#endif /* NETDATA_MAIN_H */
src/registry_person.h
+2
-2
@@ -41,8 +41,8 @@ typedef struct registry_person REGISTRY_PERSON;
41
42
// PERSON_URL
43
extern REGISTRY_PERSON_URL *registry_person_url_index_find(REGISTRY_PERSON *p, const char *url);
44
-extern REGISTRY_PERSON_URL *registry_person_url_index_add(REGISTRY_PERSON *p, REGISTRY_PERSON_URL *pu) __attribute__((returns_nonnull, warn_unused_result));
45
-extern REGISTRY_PERSON_URL *registry_person_url_index_del(REGISTRY_PERSON *p, REGISTRY_PERSON_URL *pu) __attribute__((warn_unused_result));
44
+extern REGISTRY_PERSON_URL *registry_person_url_index_add(REGISTRY_PERSON *p, REGISTRY_PERSON_URL *pu) NEVERNULL WARNUNUSED;
45
+extern REGISTRY_PERSON_URL *registry_person_url_index_del(REGISTRY_PERSON *p, REGISTRY_PERSON_URL *pu) WARNUNUSED;
46
47
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);
48
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);
src/registry_url.h
+3
-3
@@ -22,11 +22,11 @@ typedef struct registry_url REGISTRY_URL;
22
23
// REGISTRY_URL INDEX
24
extern int registry_url_compare(void *a, void *b);
25
-extern REGISTRY_URL *registry_url_index_del(REGISTRY_URL *u) __attribute__((warn_unused_result));
26
-extern REGISTRY_URL *registry_url_index_add(REGISTRY_URL *u) __attribute__((returns_nonnull, warn_unused_result));
25
+extern REGISTRY_URL *registry_url_index_del(REGISTRY_URL *u) WARNUNUSED;
26
+extern REGISTRY_URL *registry_url_index_add(REGISTRY_URL *u) NEVERNULL WARNUNUSED;
27
28
// REGISTRY_URL MANAGEMENT
29
-extern REGISTRY_URL *registry_url_get(const char *url, size_t urllen) __attribute__((returns_nonnull));
29
+extern REGISTRY_URL *registry_url_get(const char *url, size_t urllen) NEVERNULL;
30
extern void registry_url_link(REGISTRY_URL *u);
31
extern void registry_url_unlink(REGISTRY_URL *u);
32
src/web_buffer.h
+2
-2
@@ -62,9 +62,9 @@ extern BUFFER *buffer_create(size_t size);
62
extern void buffer_free(BUFFER *b);
63
extern void buffer_increase(BUFFER *b, size_t free_size_required);
64
65
-extern void buffer_snprintf(BUFFER *wb, size_t len, const char *fmt, ...) __attribute__ (( format (printf, 3, 4)));
65
+extern void buffer_snprintf(BUFFER *wb, size_t len, const char *fmt, ...) PRINTFLIKE(3, 4);
66
extern void buffer_vsprintf(BUFFER *wb, const char *fmt, va_list args);
67
-extern void buffer_sprintf(BUFFER *wb, const char *fmt, ...) __attribute__ (( format (printf, 2, 3)));
67
+extern void buffer_sprintf(BUFFER *wb, const char *fmt, ...) PRINTFLIKE(2,3);
68
extern void buffer_strcat_htmlescape(BUFFER *wb, const char *txt);
69
70
extern void buffer_char_replace(BUFFER *wb, char from, char to);