Coverage Report

Created: 2025-06-15 00:57

/src/cmp_tool/lib/common/compiler.h
Line
Count
Source
1
/**
2
 * @file   compiler.h
3
 * @author Armin Luntzer (armin.luntzer@univie.ac.at)
4
 * @date   2015
5
 *
6
 * @copyright GPLv2
7
 * This program is free software; you can redistribute it and/or modify it
8
 * under the terms and conditions of the GNU General Public License,
9
 * version 2, as published by the Free Software Foundation.
10
 *
11
 * This program is distributed in the hope it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14
 * more details.
15
 *
16
 * @brief a collection of preprocessor macros
17
 */
18
19
20
#ifndef COMPILER_H
21
#define COMPILER_H
22
23
24
/* Derived from Linux "Features Test Macro" header Convenience macros to test
25
 * the versions of gcc (or a compatible compiler).
26
 * Use them like this:
27
 *  #if GNUC_PREREQ (2,8)
28
 *   ... code requiring gcc 2.8 or later ...
29
 *  #endif
30
*/
31
32
#if defined(__GNUC__) && defined(__GNUC_MINOR__)
33
# define GNUC_PREREQ(maj, min) \
34
  ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
35
#else
36
 #define GNUC_PREREQ(maj, min) 0
37
#endif
38
39
40
/**
41
 * same with the stuff below
42
 */
43
44
#define likely(x)      __builtin_expect(!!(x), 1)
45
260k
#define unlikely(x)    __builtin_expect(!!(x), 0)
46
47
/**
48
 *
49
 * ARRAY_SIZE - get the number of elements in a visible array
50
 * @param x the array whose size you want
51
 *
52
 * This does not work on pointers, or arrays declared as [], or
53
 * function parameters.  With correct compiler support, such usage
54
 * will cause a build error
55
 */
56
57
3.35k
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
58
59
#define bitsizeof(x)  (CHAR_BIT * sizeof(x))
60
61
#define maximum_signed_value_of_type(a) \
62
    (INTMAX_MAX >> (bitsizeof(intmax_t) - bitsizeof(a)))
63
64
#define maximum_unsigned_value_of_type(a) \
65
    (UINTMAX_MAX >> (bitsizeof(uintmax_t) - bitsizeof(a)))
66
67
/*
68
 * Signed integer overflow is undefined in C, so here's a helper macro
69
 * to detect if the sum of two integers will overflow.
70
 *
71
 * Requires: a >= 0, typeof(a) equals typeof(b)
72
 */
73
#define signed_add_overflows(a, b) \
74
    ((b) > maximum_signed_value_of_type(a) - (a))
75
76
#define unsigned_add_overflows(a, b) \
77
    ((b) > maximum_unsigned_value_of_type(a) - (a))
78
79
80
132k
#define __get_unaligned_t(type, ptr) __extension__ ({            \
81
132k
  const struct { type x; } __attribute__((packed)) *__pptr = (__typeof__(__pptr))(ptr); \
82
132k
  __pptr->x;                    \
83
132k
})
84
85
4.46k
#define __put_unaligned_t(type, val, ptr) do {             \
86
4.46k
  struct { type x; } __attribute__((packed)) *__pptr = (__typeof__(__pptr))(ptr);   \
87
4.46k
  __pptr->x = (val);                  \
88
4.46k
} while (0)
89
90
91
/**
92
 * @brief read from an unaligned address
93
 *
94
 * @param ptr pointer to the address to read from (can be unaligned)
95
 *
96
 * @return the value read from the (unaligned) address in system endianness
97
 * @note the size of the value is determined by the pointer type
98
 */
99
100
132k
#define get_unaligned(ptr) __get_unaligned_t(__typeof__(*(ptr)), (ptr))
101
102
103
/**
104
 * @brief write to an unaligned address
105
 *
106
 * @param val the value to write
107
 * @param ptr pointer to the address to write to (can be unaligned)
108
 *
109
 * @note the size of the value is determined by the pointer type
110
 */
111
112
4.46k
#define put_unaligned(val, ptr) __put_unaligned_t(__typeof__(*(ptr)), (val), (ptr))
113
114
115
/**
116
 * @brief mark a variable as unused to suppress compiler warnings.
117
 *
118
 * This macro is used to indicate that a variable is intentionally left unused
119
 * in the code. It helps suppress compiler warnings about unused variables.
120
 * It also tries to prevent the actual use of the "unused" variables.
121
 */
122
123
#if GNUC_PREREQ(4, 5) || defined(__clang__)
124
#define UNUSED __attribute__((unused)) \
125
  __attribute__((deprecated ("parameter declared as UNUSED")))
126
#elif defined(__GNUC__)
127
#define UNUSED __attribute__((unused)) \
128
  __attribute__((deprecated))
129
#else
130
#define UNUSED
131
#endif
132
133
134
/**
135
 * @brief mark a variable as potentially unused to suppress compiler warnings.
136
 *
137
 * This macro is used to indicate that a variable may be intentionally left unused
138
 * in the code. It helps suppress compiler warnings about unused variables.
139
 * It does *not* protect against the actual use of the "unused" variables.
140
 */
141
142
#if (DEBUGLEVEL == 0)
143
10
#define MAYBE_UNUSED __attribute__((unused))
144
#else
145
#define MAYBE_UNUSED
146
#endif
147
148
149
/**
150
 * Compile time check usable outside of function scope.
151
 * Stolen from Linux (hpi_internal.h)
152
 */
153
#define compile_time_assert(cond, msg) UNUSED typedef char ASSERT_##msg[(cond) ? 1 : -1]
154
155
156
#endif /* COMPILER_H */