]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/compiler.h
string_utils: handle overflow correct in parse_byte_size_string()
[mirror_lxc.git] / src / lxc / compiler.h
CommitLineData
cc73685d 1/* SPDX-License-Identifier: LGPL-2.1+ */
d7f19646
CB
2
3#ifndef __LXC_COMPILER_H
4#define __LXC_COMPILER_H
5
d38dd64a
CB
6#ifndef _GNU_SOURCE
7#define _GNU_SOURCE 1
8#endif
d17947f8 9
4c5479d2
CB
10#include <stdbool.h>
11#include <linux/types.h>
12
d7f19646
CB
13#include "config.h"
14
15#ifndef thread_local
16#if __STDC_VERSION__ >= 201112L && \
17 !(defined(__STDC_NO_THREADS__) || \
18 (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16))
19#define thread_local _Thread_local
20#else
21#define thread_local __thread
22#endif
23#endif
24
fd1cf1b1
CB
25#if __GNUC__ >= 7
26#define __fallthrough __attribute__((__fallthrough__))
27#else
c73fbad1 28#define __fallthrough /* fall through */
cf0fd972
CB
29#endif
30
4c5479d2
CB
31#if defined(__GNUC__) && !defined(__clang__)
32 #if GCC_VERSION >= 50100
33 #define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1
34 #endif
35#endif
36
37#define likely(x) __builtin_expect(!!(x), 1)
38#define unlikely(x) __builtin_expect(!!(x), 0)
39#define __must_check __attribute__((__warn_unused_result__))
40
41static inline bool __must_check __must_check_overflow(bool overflow)
42{
43 return unlikely(overflow);
44}
45
46#define is_signed_type(type) (((type)(-1)) < (type)1)
47#define __type_half_max(type) ((type)1 << (8*sizeof(type) - 1 - is_signed_type(type)))
48#define type_max(T) ((T)((__type_half_max(T) - 1) + __type_half_max(T)))
49#define type_min(T) ((T)((T)-type_max(T)-(T)1))
50
51/*
52 * Avoids triggering -Wtype-limits compilation warning,
53 * while using unsigned data types to check a < 0.
54 */
55#define is_non_negative(a) ((a) > 0 || (a) == 0)
56#define is_negative(a) (!(is_non_negative(a)))
57
58#ifdef COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW
59/*
60 * For simplicity and code hygiene, the fallback code below insists on
61 * a, b and *d having the same type (similar to the min() and max()
62 * macros), whereas gcc's type-generic overflow checkers accept
63 * different types. Hence we don't just make check_add_overflow an
64 * alias for __builtin_add_overflow, but add type checks similar to
65 * below.
66 */
67#define check_add_overflow(a, b, d) __must_check_overflow(({ \
68 typeof(a) __a = (a); \
69 typeof(b) __b = (b); \
70 typeof(d) __d = (d); \
71 (void) (&__a == &__b); \
72 (void) (&__a == __d); \
73 __builtin_add_overflow(__a, __b, __d); \
74}))
75
76#define check_sub_overflow(a, b, d) __must_check_overflow(({ \
77 typeof(a) __a = (a); \
78 typeof(b) __b = (b); \
79 typeof(d) __d = (d); \
80 (void) (&__a == &__b); \
81 (void) (&__a == __d); \
82 __builtin_sub_overflow(__a, __b, __d); \
83}))
84
85#define check_mul_overflow(a, b, d) __must_check_overflow(({ \
86 typeof(a) __a = (a); \
87 typeof(b) __b = (b); \
88 typeof(d) __d = (d); \
89 (void) (&__a == &__b); \
90 (void) (&__a == __d); \
91 __builtin_mul_overflow(__a, __b, __d); \
92}))
93#else /* !COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW */
94
95/* Checking for unsigned overflow is relatively easy without causing UB. */
96#define __unsigned_add_overflow(a, b, d) ({ \
97 typeof(a) __a = (a); \
98 typeof(b) __b = (b); \
99 typeof(d) __d = (d); \
100 (void) (&__a == &__b); \
101 (void) (&__a == __d); \
102 *__d = __a + __b; \
103 *__d < __a; \
104})
105#define __unsigned_sub_overflow(a, b, d) ({ \
106 typeof(a) __a = (a); \
107 typeof(b) __b = (b); \
108 typeof(d) __d = (d); \
109 (void) (&__a == &__b); \
110 (void) (&__a == __d); \
111 *__d = __a - __b; \
112 __a < __b; \
113})
114
115/*
116 * If one of a or b is a compile-time constant, this avoids a division.
117 */
118#define __unsigned_mul_overflow(a, b, d) ({ \
119 typeof(a) __a = (a); \
120 typeof(b) __b = (b); \
121 typeof(d) __d = (d); \
122 (void) (&__a == &__b); \
123 (void) (&__a == __d); \
124 *__d = __a * __b; \
125 __builtin_constant_p(__b) ? \
126 __b > 0 && __a > type_max(typeof(__a)) / __b : \
127 __a > 0 && __b > type_max(typeof(__b)) / __a; \
128})
129
130/*
131 * For signed types, detecting overflow is much harder, especially if
132 * we want to avoid UB. But the interface of these macros is such that
133 * we must provide a result in *d, and in fact we must produce the
134 * result promised by gcc's builtins, which is simply the possibly
135 * wrapped-around value. Fortunately, we can just formally do the
136 * operations in the widest relevant unsigned type (u64) and then
137 * truncate the result - gcc is smart enough to generate the same code
138 * with and without the (u64) casts.
139 */
140
141/*
142 * Adding two signed integers can overflow only if they have the same
143 * sign, and overflow has happened iff the result has the opposite
144 * sign.
145 */
146#define __signed_add_overflow(a, b, d) ({ \
147 typeof(a) __a = (a); \
148 typeof(b) __b = (b); \
149 typeof(d) __d = (d); \
150 (void) (&__a == &__b); \
151 (void) (&__a == __d); \
152 *__d = (__u64)__a + (__u64)__b; \
153 (((~(__a ^ __b)) & (*__d ^ __a)) \
154 & type_min(typeof(__a))) != 0; \
155})
156
157/*
158 * Subtraction is similar, except that overflow can now happen only
159 * when the signs are opposite. In this case, overflow has happened if
160 * the result has the opposite sign of a.
161 */
162#define __signed_sub_overflow(a, b, d) ({ \
163 typeof(a) __a = (a); \
164 typeof(b) __b = (b); \
165 typeof(d) __d = (d); \
166 (void) (&__a == &__b); \
167 (void) (&__a == __d); \
168 *__d = (__u64)__a - (__u64)__b; \
169 ((((__a ^ __b)) & (*__d ^ __a)) \
170 & type_min(typeof(__a))) != 0; \
171})
172
173/*
174 * Signed multiplication is rather hard. gcc always follows C99, so
175 * division is truncated towards 0. This means that we can write the
176 * overflow check like this:
177 *
178 * (a > 0 && (b > MAX/a || b < MIN/a)) ||
179 * (a < -1 && (b > MIN/a || b < MAX/a) ||
180 * (a == -1 && b == MIN)
181 *
182 * The redundant casts of -1 are to silence an annoying -Wtype-limits
183 * (included in -Wextra) warning: When the type is u8 or u16, the
184 * __b_c_e in check_mul_overflow obviously selects
185 * __unsigned_mul_overflow, but unfortunately gcc still parses this
186 * code and warns about the limited range of __b.
187 */
188
189#define __signed_mul_overflow(a, b, d) ({ \
190 typeof(a) __a = (a); \
191 typeof(b) __b = (b); \
192 typeof(d) __d = (d); \
193 typeof(a) __tmax = type_max(typeof(a)); \
194 typeof(a) __tmin = type_min(typeof(a)); \
195 (void) (&__a == &__b); \
196 (void) (&__a == __d); \
197 *__d = (__u64)__a * (__u64)__b; \
198 (__b > 0 && (__a > __tmax/__b || __a < __tmin/__b)) || \
199 (__b < (typeof(__b))-1 && (__a > __tmin/__b || __a < __tmax/__b)) || \
200 (__b == (typeof(__b))-1 && __a == __tmin); \
201})
202
203
204#define check_add_overflow(a, b, d) __must_check_overflow( \
205 __builtin_choose_expr(is_signed_type(typeof(a)), \
206 __signed_add_overflow(a, b, d), \
207 __unsigned_add_overflow(a, b, d)))
208
209#define check_sub_overflow(a, b, d) __must_check_overflow( \
210 __builtin_choose_expr(is_signed_type(typeof(a)), \
211 __signed_sub_overflow(a, b, d), \
212 __unsigned_sub_overflow(a, b, d)))
213
214#define check_mul_overflow(a, b, d) __must_check_overflow( \
215 __builtin_choose_expr(is_signed_type(typeof(a)), \
216 __signed_mul_overflow(a, b, d), \
217 __unsigned_mul_overflow(a, b, d)))
218
219#endif /* COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW */
220
d17947f8
CB
221#ifndef __noreturn
222# if __STDC_VERSION__ >= 201112L
223# if !IS_BIONIC
224# define __noreturn _Noreturn
225# else
226# define __noreturn __attribute__((__noreturn__))
227# endif
228# elif IS_BIONIC
229# define __noreturn __attribute__((__noreturn__))
230# else
231# define __noreturn __attribute__((noreturn))
232# endif
cf0fd972
CB
233#endif
234
afeec9b7
CB
235#ifndef __hot
236# define __hot __attribute__((hot))
237#endif
238
633cb8be
CB
239#ifndef __returns_twice
240#define __returns_twice __attribute__((returns_twice))
241#endif
242
1a080cd7
CB
243/* This attribute is required to silence clang warnings */
244#if defined(__GNUC__)
53675a8d 245#define __lxc_unused __attribute__ ((unused))
1a080cd7 246#else
53675a8d 247#define __lxc_unused
1a080cd7
CB
248#endif
249
ebbca852
MH
250/* Indicates taking ownership */
251#define __owns
252
b857f4be
CB
253#define __cgfsng_ops
254
674c9692 255/* access attribute */
3d971319 256#define __access_r_nosize(x)
674c9692
CB
257#define __access_r(x, y)
258#define __access_w(x, y)
259#define __access_rw(x, y)
260
261#ifdef __has_attribute
262#if __has_attribute(access)
263#undef __access_r
264#define __access_r(x, y) __attribute__((access(read_only, x, y)))
265
3d971319
CB
266#undef __access_r_nosize
267#define __access_r_nosize(x) __attribute__((access(read_only, x)))
268
674c9692
CB
269#undef __access_w
270#define __access_w(x, y) __attribute__((access(write_only, x, y)))
271
272#undef __access_rw
273#define __access_rw(x, y) __attribute__((access(read_write, x, y)))
274#endif
275#endif
276
6822ba9b
CB
277#ifndef __hidden
278#define __hidden __attribute__((visibility("hidden")))
279#endif
280
a7692df5
CB
281#ifndef __public
282#define __public __attribute__((visibility("default")))
283#endif
284
d7f19646 285#endif /* __LXC_COMPILER_H */