|
43 | 43 | #define is_non_negative(a) ((a) > 0 || (a) == 0) |
44 | 44 | #define is_negative(a) (!(is_non_negative(a))) |
45 | 45 |
|
| 46 | +/* |
| 47 | + * Allows for effectively applying __must_check to a macro so we can have |
| 48 | + * both the type-agnostic benefits of the macros while also being able to |
| 49 | + * enforce that the return value is, in fact, checked. |
| 50 | + */ |
| 51 | +static inline bool __must_check __must_check_overflow(bool overflow) |
| 52 | +{ |
| 53 | + return unlikely(overflow); |
| 54 | +} |
| 55 | + |
46 | 56 | #ifdef COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW |
47 | 57 | /* |
48 | 58 | * For simplicity and code hygiene, the fallback code below insists on |
|
52 | 62 | * alias for __builtin_add_overflow, but add type checks similar to |
53 | 63 | * below. |
54 | 64 | */ |
55 | | -#define check_add_overflow(a, b, d) ({ \ |
| 65 | +#define check_add_overflow(a, b, d) __must_check_overflow(({ \ |
56 | 66 | typeof(a) __a = (a); \ |
57 | 67 | typeof(b) __b = (b); \ |
58 | 68 | typeof(d) __d = (d); \ |
59 | 69 | (void) (&__a == &__b); \ |
60 | 70 | (void) (&__a == __d); \ |
61 | 71 | __builtin_add_overflow(__a, __b, __d); \ |
62 | | -}) |
| 72 | +})) |
63 | 73 |
|
64 | | -#define check_sub_overflow(a, b, d) ({ \ |
| 74 | +#define check_sub_overflow(a, b, d) __must_check_overflow(({ \ |
65 | 75 | typeof(a) __a = (a); \ |
66 | 76 | typeof(b) __b = (b); \ |
67 | 77 | typeof(d) __d = (d); \ |
68 | 78 | (void) (&__a == &__b); \ |
69 | 79 | (void) (&__a == __d); \ |
70 | 80 | __builtin_sub_overflow(__a, __b, __d); \ |
71 | | -}) |
| 81 | +})) |
72 | 82 |
|
73 | | -#define check_mul_overflow(a, b, d) ({ \ |
| 83 | +#define check_mul_overflow(a, b, d) __must_check_overflow(({ \ |
74 | 84 | typeof(a) __a = (a); \ |
75 | 85 | typeof(b) __b = (b); \ |
76 | 86 | typeof(d) __d = (d); \ |
77 | 87 | (void) (&__a == &__b); \ |
78 | 88 | (void) (&__a == __d); \ |
79 | 89 | __builtin_mul_overflow(__a, __b, __d); \ |
80 | | -}) |
| 90 | +})) |
81 | 91 |
|
82 | 92 | #else |
83 | 93 |
|
|
190 | 200 | }) |
191 | 201 |
|
192 | 202 |
|
193 | | -#define check_add_overflow(a, b, d) \ |
| 203 | +#define check_add_overflow(a, b, d) __must_check_overflow( \ |
194 | 204 | __builtin_choose_expr(is_signed_type(typeof(a)), \ |
195 | 205 | __signed_add_overflow(a, b, d), \ |
196 | | - __unsigned_add_overflow(a, b, d)) |
| 206 | + __unsigned_add_overflow(a, b, d))) |
197 | 207 |
|
198 | | -#define check_sub_overflow(a, b, d) \ |
| 208 | +#define check_sub_overflow(a, b, d) __must_check_overflow( \ |
199 | 209 | __builtin_choose_expr(is_signed_type(typeof(a)), \ |
200 | 210 | __signed_sub_overflow(a, b, d), \ |
201 | | - __unsigned_sub_overflow(a, b, d)) |
| 211 | + __unsigned_sub_overflow(a, b, d))) |
202 | 212 |
|
203 | | -#define check_mul_overflow(a, b, d) \ |
| 213 | +#define check_mul_overflow(a, b, d) __must_check_overflow( \ |
204 | 214 | __builtin_choose_expr(is_signed_type(typeof(a)), \ |
205 | 215 | __signed_mul_overflow(a, b, d), \ |
206 | | - __unsigned_mul_overflow(a, b, d)) |
207 | | - |
| 216 | + __unsigned_mul_overflow(a, b, d))) |
208 | 217 |
|
209 | 218 | #endif /* COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW */ |
210 | 219 |
|
|
227 | 236 | * '*d' will hold the results of the attempted shift, but is not |
228 | 237 | * considered "safe for use" if false is returned. |
229 | 238 | */ |
230 | | -#define check_shl_overflow(a, s, d) ({ \ |
| 239 | +#define check_shl_overflow(a, s, d) __must_check_overflow(({ \ |
231 | 240 | typeof(a) _a = a; \ |
232 | 241 | typeof(s) _s = s; \ |
233 | 242 | typeof(d) _d = d; \ |
|
237 | 246 | *_d = (_a_full << _to_shift); \ |
238 | 247 | (_to_shift != _s || is_negative(*_d) || is_negative(_a) || \ |
239 | 248 | (*_d >> _to_shift) != _a); \ |
240 | | -}) |
| 249 | +})) |
241 | 250 |
|
242 | 251 | /** |
243 | 252 | * array_size() - Calculate size of 2-dimensional array. |
|
0 commit comments