The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
build.h
Go to the documentation of this file.
1 #pragma once
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16  */
17 
18 /**
19  * $Id: 52c460c5cddf37d57cbd8ce89e0f4bffb3239e6d $
20  *
21  * @file include/build.h
22  * @brief Source control functions
23  *
24  * @copyright 2013 The FreeRADIUS server project
25  */
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 /** For systems with an old version libc, define static_assert.
32  *
33  */
34 #ifndef static_assert
35 # define static_assert _Static_assert
36 # else
37 # include <assert.h>
38 #endif
39 
40 /*
41  * Static analyzers don't notice or can't infer some properties
42  * of the code, and hence may give false positives. To deal with
43  * them, there is some conditionally compiled code in various
44  * places. The following lets the code change minimally if and
45  * when new static analyzers are added.
46  */
47 #ifdef __clang_analyzer__
48 #define STATIC_ANALYZER 1
49 #endif
50 #ifdef __COVERITY__
51 #define STATIC_ANALYZER 1
52 #endif
53 
54 /*
55  * Reduce spurious errors from static analyzers by having
56  * all paths that find the da to be NULL, result
57  * in program exit.
58  */
59 #ifdef STATIC_ANALYZER
60 # define WITH_VERIFY_PTR 1
61 #endif
62 
63 /*
64  * GCC uses __SANITIZE_ADDRESS__, clang uses __has_feature, which
65  * GCC complains about.
66  */
67 #ifndef __SANITIZE_ADDRESS__
68 #ifdef __has_feature
69 #if __has_feature(address_sanitizer)
70 #define __SANITIZE_ADDRESS__ (1)
71 #endif
72 #endif
73 #endif
74 
75 /*
76  * Basic headers we want everywhere
77  */
78 #include <stdint.h>
79 #include <stddef.h>
80 #include <string.h>
81 
82 /*
83  * These are compile time options to toggle whether
84  * we're building with thread support.
85  *
86  * With EMSCRIPTEN threading support isn't guaranteed
87  * as many browsers have explicitly disabled support
88  * due to spectre attacks.
89  */
90 #if (defined(__EMSCRIPTEN__) && defined(__EMSCRIPTEN_PTHREADS__)) || !defined(__EMSCRIPTEN__) && defined(HAVE_PTHREAD_H)
91 # define HAVE_PTHREADS 1
92 #endif
93 
94 /*
95  * GCC will sometimes define "unix" as well as "__unix",
96  * which gets confusing and is unnecessary.
97  */
98 #undef unix
99 
100 /** Evaluates to +1 for a > b, and -1 for a < b
101  */
102 #define CMP_PREFER_SMALLER(_a,_b) (((_a) > (_b)) - ((_a) < (_b)))
103 
104 /** Evaluates to -1 for a > b, and +1 for a < b
105  */
106 #define CMP_PREFER_LARGER(_a,_b) (((_a) < (_b)) - ((_a) > (_b)))
107 
108 /** Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want _an_ ordering.
109  */
110 #define CMP(_a, _b) CMP_PREFER_SMALLER(_a, _b)
111 
112 /** Return if the comparison is not 0 (is unequal)
113  *
114  * @param[in] _a pointer to first structure.
115  * @param[in] _b pointer to second structure.
116  * @param[in] _field within the structs to compare.
117  * @return The result of the comparison.
118  */
119 #define CMP_RETURN(_a, _b, _field) \
120 do { \
121  int8_t _ret = CMP((_a)->_field, (_b)->_field); \
122  if (_ret != 0) return _ret; \
123 } while (0)
124 
125 /** memcmp function which has similar behaviour as strncmp
126  *
127  * @param[in] a First thing to compare.
128  * @param[in] b Second thing to compare.
129  * @param[in] a_len Length of first thing.
130  * @param[in] b_len Length of second thing.
131  * @return
132  * - +1 if a > b
133  * - 0 if a == b
134  * - -1 if a < b
135  */
136 static inline int8_t memcmp_return(void const *a, void const *b, size_t a_len, size_t b_len)
137 {
138  size_t cmp_len = (a_len < b_len) ? a_len : b_len;
139  int8_t l_ret = CMP(a_len, b_len);
140  int8_t ret;
141  ret = CMP(memcmp(a, b, cmp_len), 0);
142  if (ret != 0) return ret;
143  return l_ret;
144 }
145 
146 /** Return if the contents of the specified field is not identical between the specified structures
147  *
148  * @param[in] _a pointer to first structure.
149  * @param[in] _b pointer to second structure.
150  * @param[in] _field within the structs to compare.
151  * @param[in] _len_field within the structs, specifying the length of the data.
152  * @return The result of the comparison.
153  */
154 #define MEMCMP_RETURN(_a, _b, _field, _len_field) \
155 do { \
156  int8_t _ret = memcmp_return((_a)->_field, (_b)->_field, (_a)->_len_field, (_b)->_len_field); \
157  if (_ret != 0) return _ret; \
158 } while (0)
159 
160 /** Remove const qualification from a pointer
161  *
162  * @param[in] _type The non-const version of the type.
163  * @param[in] _ptr to de-const.
164  */
165 #define UNCONST(_type, _ptr) ((_type)((uintptr_t)(_ptr)))
166 
167 /** Typeof field
168  *
169  * @param[in] _type struct type containing the field.
170  * @param[in] _field to return the type of.
171  */
172 #define typeof_field(_type, _field) __typeof__(((_type *)NULL)->_field)
173 
174 /** HEX concatenation macros
175  *
176  */
177 #ifndef HEXIFY
178 # define XHEXIFY4(b1,b2,b3,b4) (0x ## b1 ## b2 ## b3 ## b4)
179 # define HEXIFY4(b1,b2,b3,b4) XHEXIFY4(b1, b2, b3, b4)
180 
181 # define XHEXIFY3(b1,b2,b3) (0x ## b1 ## b2 ## b3)
182 # define HEXIFY3(b1,b2,b3) XHEXIFY3(b1, b2, b3)
183 
184 # define XHEXIFY2(b1,b2) (0x ## b1 ## b2)
185 # define HEXIFY2(b1,b2) XHEXIFY2(b1, b2)
186 
187 # define XHEXIFY(b1) (0x ## b1)
188 # define HEXIFY(b1) XHEXIFY(b1)
189 #endif
190 
191 /** The ubiquitous stringify macros
192  *
193  */
194 #define XSTRINGIFY(x) #x
195 #define STRINGIFY(x) XSTRINGIFY(x)
196 #define JOINSTR(x,y) XSTRINGIFY(x ## y)
197 
198 /** Join two values without stringifying
199  *
200  * Useful for calling different macros based on the output of
201 */
202 #define _JOIN(x,y) x ## y
203 #define JOIN(x,y) _JOIN(x,y)
204 
205 /** Helper for initialising arrays of string literals
206  */
207 #define L(_str) { _str, sizeof(_str) - 1 }
208 
209 /** Fill macros for array initialisation
210  */
211 #define F1(_idx, _val) [_idx] = _val
212 #define F2(_idx, _val) F1(_idx, _val), F1(_idx + 1, _val)
213 #define F4(_idx, _val) F2(_idx, _val), F2(_idx + 2, _val)
214 #define F8(_idx, _val) F4(_idx, _val), F4(_idx + 4, _val)
215 #define F16(_idx, _val) F8(_idx, _val), F8(_idx + 8, _val)
216 #define F32(_idx, _val) F16(_idx, _val), F16(_idx + 16, _val)
217 #define F64(_idx, _val) F32(_idx, _val), F32(_idx + 32, _val)
218 #define F128(_idx, _val) F64(_idx, _val), F64(_idx + 64, _val)
219 #define F256(_idx, _val) F128(_idx, _val), F128(_idx + 128, _val)
220 
221 /** Variadic macro framework
222  */
223 
224 /**
225  * The VA_NARG macro evaluates to the number of arguments that have been
226  * passed to it.
227  *
228  * Laurent Deniau, "__VA_NARG__," 17 January 2006, <comp.std.c> (29 November 2007).
229  */
230 #define VA_ARG_N( \
231  _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
232  _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
233  _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
234  _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
235  _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
236  _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
237  _61,_62,_63,N,...) N
238 
239 #define VA_RSEQ_N() \
240  63,62,61,60, \
241  59,58,57,56,55,54,53,52,51,50, \
242  49,48,47,46,45,44,43,42,41,40, \
243  39,38,37,36,35,34,33,32,31,30, \
244  29,28,27,26,25,24,23,22,21,20, \
245  19,18,17,16,15,14,13,12,11,10, \
246  9,8,7,6,5,4,3,2,1,0
247 
248 #define _VA_NARG(...) VA_ARG_N(__VA_ARGS__)
249 
250 /** Return the number of variadic arguments up to 64
251  *
252  * @param[in] ... Variadic arguments to count.
253  */
254 #define VA_NARG(...) _VA_NARG(__VA_ARGS__, VA_RSEQ_N())
255 
256 
257 /** Pass caller information to the function
258  *
259  */
260 #ifndef NDEBUG
261 # define NDEBUG_LOCATION_ARGS char const *file, int line,
262 # define NDEBUG_LOCATION_VALS file, line,
263 # define NDEBUG_LOCATION_EXP __FILE__, __LINE__,
264 # define NDEBUG_LOCATION_NONNULL(_num) ((_num) + 2)
265 #else
266 # define NDEBUG_LOCATION_ARGS
267 # define NDEBUG_LOCATION_VALS
268 # define NDEBUG_LOCATION_EXP
269 # define NDEBUG_LOCATION_NONNULL(_num) (_num)
270 #endif
271 
272 /** Check if a given variable is the _const or not
273  *
274  * @param[in] _type The base type of the variable (should not be marked const)
275  * @param[in] _var to check.
276  */
277 #define IS_CONST(_type, _var) \
278  _Generic((_var), \
279  _type: false, \
280  const _type: true \
281  )
282 
283 /** Check if a given variable is the const or unconst version of a type
284  *
285  * Expands to _var if _var matches type, otherwise throws a compiler error.
286  *
287  * Useful for creating typesafe wrapper macros around functions which take
288  * void *s.
289  *
290  * @param[in] _type The base type of the variable (should not be marked const)
291  * @param[in] _var to check.
292  */
293 #define IS_TYPE(_type, _var) \
294  _Generic((_var), \
295  _type: _var, \
296  const _type: _var \
297  )
298 /*
299  * Mark variables as unused
300  */
301 #define UNUSED_VAR(_x) ((void)_x)
302 
303 /** Pad _x to the next multiple of _y
304  *
305  */
306 #define PAD(_x, _y) (_y - ((_x) % _y))
307 
308 /** Should be placed before the function return type
309  *
310  */
311 #define NEVER_RETURNS _Noreturn
312 #define HIDDEN CC_HINT(visibility("hidden"))
313 #define UNUSED CC_HINT(unused)
314 
315 /** clang 10 doesn't recognised the FALL-THROUGH comment anymore
316  */
317 #if (defined(__clang__) && (__clang_major__ >= 10)) || (defined(__GNUC__) && __GNUC__ >= 7)
318 # define FALL_THROUGH CC_HINT(fallthrough)
319 #else
320 # define FALL_THROUGH ((void)0)
321 #endif
322 
323 #ifndef NDEBUG
324 # define NDEBUG_UNUSED
325 #else
326 # define NDEBUG_UNUSED UNUSED
327 #endif
328 
329 #define BLANK_FORMAT " " /* GCC_LINT whines about empty formats */
330 
331 /*
332  * struct field size
333  */
334 #define SIZEOF_MEMBER(_t, _m) sizeof(((_t *)0)->_m)
335 #define NUM_ELEMENTS(_t) (sizeof((_t)) / sizeof((_t)[0]))
336 
337 /*
338  * For use with multidimensional arrays where
339  * the deeper array element has a size smaller than
340  * a pointer i.e. char foo[n][m]
341  */
342 #define NUM_PTR_ELEMENTS(_t) (sizeof((_t)) / sizeof(void *))
343 
344 /*
345  * Type checking
346  */
347 
348 /** Check if two types are compatible (the C11 way)
349  *
350  * Expands to 1 if types are compatible, else 0.
351  *
352  * @param[in] _x pointer to check.
353  * @param[in] _t type to check compatibility with.
354  */
355 #define IS_COMPATIBLE(_x, _t) _Generic(_x, _t:1, default: 0)
356 
357 /** Check if a field in a struct is compatible (the C11 way)
358  *
359  * Expands to 1 if types are compatible, else 0.
360  *
361  * @param[in] _s struct to check.
362  * @param[in] _f field in struct.
363  * @param[in] _t type to check compatibility with.
364  */
365 #define IS_FIELD_COMPATIBLE(_s, _f, _t) _Generic(((_s *)0)->_f, _t:1, default: 0)
366 
367 /*
368  * Only use GCC __attribute__ if were building with a GCClike
369  * compiler.
370  */
371 #ifdef __GNUC__
372 # define CC_HINT(...) __attribute__((__VA_ARGS__))
373 # define likely(_x) __builtin_expect((_x), 1)
374 # define unlikely(_x) __builtin_expect((_x), 0)
375 # define unpredictable(_x) __builtin_unpredictable((_x))
376 #else
377 # define CC_HINT(...)
378 # define likely(_x) _x
379 # define unlikely(_x) _x
380 # define unpredictable(_x) _x
381 #endif
382 
383 /*
384  * GNU version check
385  */
386 #ifdef __GNUC__
387 #define __GNUC_PREREQ__(x, y) \
388  ((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) || \
389  (__GNUC__ > (x)))
390 #else
391 #define __GNUC_PREREQ__(x, y) 0
392 #endif
393 
394 
395 /*
396  * Macros to add pragmas
397  */
398 #define PRAGMA(_x) _Pragma(#_x)
399 
400 /*
401  * Handle acquire/release macros
402  */
403 #if defined(__clang__) && (__clang_major__ >= 13)
404 # define CC_ACQUIRE_HANDLE(_tag) CC_HINT(acquire_handle(_tag))
405 # define CC_USE_HANDLE(_tag) CC_HINT(use_handle(_tag))
406 # define CC_RELEASE_HANDLE(_tag) CC_HINT(release_handle(_tag))
407 #else
408 # define CC_ACQUIRE_HANDLE(_tag)
409 # define CC_USE_HANDLE(_tag)
410 # define CC_RELEASE_HANDLE(_tag)
411 #endif
412 
413 /*
414  * Disable various forms of ubsan
415  */
416 #ifndef __has_feature
417 # define __has_feature(_x) 0
418 #endif
419 #if defined(__clang__) && __has_feature(undefined_behavior_sanitizer)
420 # define CC_NO_UBSAN(_sanitize) __attribute__((no_sanitize(STRINGIFY(_sanitize))))
421 #elif __GNUC_PREREQ__(4, 9) && defined(__SANITIZE_UNDEFINED__)
422 # define CC_NO_UBSAN(_sanitize) __attribute__((no_sanitize_undefined))
423 #else
424 # define CC_NO_UBSAN(_sanitize)
425 #endif
426 
427 /*
428  * Disable sanitizers for undefined behaviour
429  */
430 #if defined(__clang__)
431 # define CC_NO_SANITIZE_UNDEFINED(_what) CC_HINT(no_sanitize(_what))
432 #else
433 # define CC_NO_SANITIZE_UNDEFINED(_what)
434 #endif
435 
436 /*
437  * Macros for controlling warnings in GCC >= 4.2 and clang >= 2.8
438  */
439 #if defined(__clang__) && ((__clang_major__ * 100) + __clang_minor__ >= 208)
440 # define DIAG_UNKNOWN_PRAGMAS unknown-pragmas
441 # define DIAG_PRAGMA(_x) PRAGMA(clang diagnostic _x)
442 # define DIAG_OFF(_x) DIAG_PRAGMA(ignored JOINSTR(-W,_x))
443 # define DIAG_ON(_x) DIAG_PRAGMA(warning JOINSTR(-W,_x))
444 # define DIAG_PUSH() DIAG_PRAGMA(push)
445 # define DIAG_POP() DIAG_PRAGMA(pop)
446 #elif !defined(__clang__) && defined(__GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 402
447 # define DIAG_UNKNOWN_PRAGMAS pragmas
448 # define DIAG_PRAGMA(_x) PRAGMA(GCC diagnostic _x)
449 # define DIAG_OFF(_x) DIAG_PRAGMA(ignored JOINSTR(-W,_x))
450 # define DIAG_ON(_x) DIAG_PRAGMA(warning JOINSTR(-W,_x))
451 # define DIAG_PUSH() DIAG_PRAGMA(push)
452 # define DIAG_POP() DIAG_PRAGMA(pop)
453 #else
454 # define DIAG_UNKNOWN_PRAGMAS
455 # define DIAG_OFF(_x)
456 # define DIAG_ON(_x)
457 # define DIAG_PUSH()
458 # define DIAG_POP()
459 #endif
460 
461 /*
462  * For dealing with APIs which are only deprecated in OSX (like the OpenSSL API)
463  */
464 #ifdef __APPLE__
465 # define USES_APPLE_DEPRECATED_API DIAG_OFF(deprecated-declarations)
466 # define USES_APPLE_RST DIAG_ON(deprecated-declarations)
467 #else
468 # define USES_APPLE_DEPRECATED_API
469 # define USES_APPLE_RST
470 #endif
471 
472 #if defined(__GNUC__)
473 /* force inclusion of ident keywords in the face of optimization */
474 # define RCSID(id) static char const rcsid[] __attribute__ ((used)) = id;
475 # define RCSIDH(h, id) static char const rcsid_ ## h [] __attribute__ ((used)) = id;
476 #elif defined(__SUNPRO_C)
477 /* put ident keyword into comment section (nicer than gcc way) */
478 # define RCSID(id) PRAGMA(sun ident id)
479 # define RCSIDH(h, id) PRAGMA(sun ident id)
480 #else
481 # define RCSID(id)
482 # define RCSIDH(h, id)
483 #endif
484 #ifdef __cplusplus
485 }
486 #endif
487 
488 /*
489  * For closing macros which open a code block e.g. fr_rb_inorder_foreach
490  */
491 #define endforeach }
492 
493 /* Explicitly evaluate and ignore an expression
494  *
495  * Why this macro?
496  * 1. gcc will warn about unused return values, even with the traditional cast to void.
497  * 2. There are cases in which an error case wants to clean up, but the function to
498  * clean up itself returns a status. In this context you don't care, but then you
499  * have the Scylla of unused return value and the Charybdis of Coverity complaining
500  * about an if that doesn't affect control flow. The following evaluates _expr and
501  * stores it in a variable marked as unused
502  * @param _expr The expression to be evaluated and ignored
503  * @param _type The type of the expression
504  */
505 #define IGNORE(_expr, _type) \
506  do { \
507  _type ignored UNUSED = (_expr); \
508  } while (0)
static int8_t memcmp_return(void const *a, void const *b, size_t a_len, size_t b_len)
memcmp function which has similar behaviour as strncmp
Definition: build.h:136
#define CMP(_a, _b)
Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want an ordering.
Definition: build.h:110