]> git.proxmox.com Git - mirror_frr.git/blame - lib/compiler.h
Merge pull request #4482 from opensourcerouting/warnings-20190606
[mirror_frr.git] / lib / compiler.h
CommitLineData
de1a880c
DL
1/*
2 * Copyright (c) 2015-2017 David Lamparter, for NetDEF, Inc.
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _FRR_COMPILER_H
18#define _FRR_COMPILER_H
19
5e244469
RW
20#ifdef __cplusplus
21extern "C" {
22#endif
23
de1a880c
DL
24/* function attributes, use like
25 * void prototype(void) __attribute__((_CONSTRUCTOR(100)));
26 */
27#if defined(__clang__)
996c9314 28#if __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 5)
de1a880c 29# define _RET_NONNULL , returns_nonnull
996c9314 30#endif
bd27ea43
DL
31#if __has_attribute(fallthrough)
32# define _FALLTHROUGH __attribute__((fallthrough));
33#endif
de1a880c 34# define _CONSTRUCTOR(x) constructor(x)
bcea0c0f 35# define _DEPRECATED(x) deprecated(x)
111a04f7
DL
36# if __has_builtin(assume)
37# define assume(x) __builtin_assume(x)
38# endif
de1a880c 39#elif defined(__GNUC__)
996c9314 40#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)
de1a880c 41# define _RET_NONNULL , returns_nonnull
996c9314
LB
42#endif
43#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
de1a880c
DL
44# define _CONSTRUCTOR(x) constructor(x)
45# define _DESTRUCTOR(x) destructor(x)
46# define _ALLOC_SIZE(x) alloc_size(x)
996c9314 47#endif
bcea0c0f
DL
48#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
49# define _DEPRECATED(x) deprecated(x)
111a04f7
DL
50# define assume(x) do { if (!(x)) __builtin_unreachable(); } while (0)
51#endif
52#if __GNUC__ < 5
53# define __has_attribute(x) 0
bcea0c0f 54#endif
bd27ea43
DL
55#if __GNUC__ >= 7
56# define _FALLTHROUGH __attribute__((fallthrough));
57#endif
de1a880c
DL
58#endif
59
111a04f7
DL
60#if __has_attribute(hot)
61# define _OPTIMIZE_HOT __attribute__((hot))
62#else
63# define _OPTIMIZE_HOT
64#endif
65#if __has_attribute(optimize)
66# define _OPTIMIZE_O3 __attribute__((optimize("3")))
67#else
68# define _OPTIMIZE_O3
69#endif
70#define OPTIMIZE _OPTIMIZE_O3 _OPTIMIZE_HOT
71
8be3678a
DL
72#if !defined(__GNUC__)
73#error module code needs GCC visibility extensions
74#elif __GNUC__ < 4
75#error module code needs GCC visibility extensions
76#else
77# define DSO_PUBLIC __attribute__ ((visibility ("default")))
78# define DSO_SELF __attribute__ ((visibility ("protected")))
79# define DSO_LOCAL __attribute__ ((visibility ("hidden")))
80#endif
81
de1a880c
DL
82#ifdef __sun
83/* Solaris doesn't do constructor priorities due to linker restrictions */
996c9314
LB
84#undef _CONSTRUCTOR
85#undef _DESTRUCTOR
de1a880c
DL
86#endif
87
88/* fallback versions */
89#ifndef _RET_NONNULL
90# define _RET_NONNULL
91#endif
92#ifndef _CONSTRUCTOR
93# define _CONSTRUCTOR(x) constructor
94#endif
95#ifndef _DESTRUCTOR
96# define _DESTRUCTOR(x) destructor
97#endif
98#ifndef _ALLOC_SIZE
99# define _ALLOC_SIZE(x)
100#endif
bd27ea43
DL
101#ifndef _FALLTHROUGH
102#define _FALLTHROUGH
103#endif
bcea0c0f
DL
104#ifndef _DEPRECATED
105#define _DEPRECATED(x) deprecated
106#endif
111a04f7
DL
107#ifndef assume
108#define assume(x)
109#endif
de1a880c 110
3b18b6c0
DL
111/* pure = function does not modify memory & return value is the same if
112 * memory hasn't changed (=> allows compiler to optimize)
113 *
114 * Mostly autodetected by the compiler if function body is available (i.e.
115 * static inline functions in headers). Since that implies it should only be
116 * used in headers for non-inline functions, the "extern" is included here.
117 */
118#define ext_pure extern __attribute__((pure))
119
0d019561
DL
120/* for helper functions defined inside macros */
121#define macro_inline static inline __attribute__((unused))
122#define macro_pure static inline __attribute__((unused, pure))
123
de1a880c
DL
124/*
125 * for warnings on macros, put in the macro content like this:
126 * #define MACRO BLA CPP_WARN("MACRO has been deprecated")
127 */
128#define CPP_STR(X) #X
129
130#if defined(__ICC)
131#define CPP_NOTICE(text) _Pragma(CPP_STR(message __FILE__ ": " text))
132#define CPP_WARN(text) CPP_NOTICE(text)
133
134#elif (defined(__GNUC__) \
135 && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) \
136 || (defined(__clang__) \
137 && (__clang_major__ >= 4 \
138 || (__clang_major__ == 3 && __clang_minor__ >= 5)))
139#define CPP_WARN(text) _Pragma(CPP_STR(GCC warning text))
140#define CPP_NOTICE(text) _Pragma(CPP_STR(message text))
141
142#else
143#define CPP_WARN(text)
ec40eaf9 144#define CPP_NOTICE(text)
de1a880c
DL
145#endif
146
0d019561
DL
147/* MAX / MIN are not commonly defined, but useful */
148/* note: glibc sys/param.h has #define MIN(a,b) (((a)<(b))?(a):(b)) */
149#ifdef MAX
150#undef MAX
151#endif
152#define MAX(a, b) \
153 ({ \
154 typeof(a) _max_a = (a); \
155 typeof(b) _max_b = (b); \
156 _max_a > _max_b ? _max_a : _max_b; \
157 })
158#ifdef MIN
159#undef MIN
160#endif
161#define MIN(a, b) \
162 ({ \
163 typeof(a) _min_a = (a); \
164 typeof(b) _min_b = (b); \
165 _min_a < _min_b ? _min_a : _min_b; \
166 })
167
168#ifndef offsetof
169#ifdef __compiler_offsetof
170#define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE,MEMBER)
171#else
172#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
173#endif
174#endif
175
176/* this variant of container_of() retains 'const' on pointers without needing
177 * to be told to do so. The following will all work without warning:
178 *
179 * struct member *p;
180 * const struct member *cp;
181 *
182 * const struct cont *x = container_of(cp, struct cont, member);
183 * const struct cont *x = container_of(cp, const struct cont, member);
184 * const struct cont *x = container_of(p, struct cont, member);
185 * const struct cont *x = container_of(p, const struct cont, member);
186 * struct cont *x = container_of(p, struct cont, member);
187 *
188 * but the following will generate warnings about stripping const:
189 *
190 * struct cont *x = container_of(cp, struct cont, member);
191 * struct cont *x = container_of(cp, const struct cont, member);
192 * struct cont *x = container_of(p, const struct cont, member);
193 */
194#ifdef container_of
195#undef container_of
196#endif
197#define container_of(ptr, type, member) \
198 (__builtin_choose_expr( \
199 __builtin_types_compatible_p(typeof(&((type *)0)->member), \
200 typeof(ptr)) \
201 || __builtin_types_compatible_p(void *, typeof(ptr)), \
202 ({ \
203 typeof(((type *)0)->member) *__mptr = (void *)(ptr); \
204 (type *)((char *)__mptr - offsetof(type, member)); \
205 }), \
206 ({ \
207 typeof(((const type *)0)->member) *__mptr = (ptr); \
208 (const type *)((const char *)__mptr - \
209 offsetof(type, member)); \
210 }) \
211 ))
212
213#define container_of_null(ptr, type, member) \
214 ({ \
215 typeof(ptr) _tmp = (ptr); \
216 _tmp ? container_of(_tmp, type, member) : NULL; \
217 })
218
219#define array_size(ar) (sizeof(ar) / sizeof(ar[0]))
220
5e244469
RW
221#ifdef __cplusplus
222}
223#endif
224
de1a880c 225#endif /* _FRR_COMPILER_H */