4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of Red Hat nor the names of its contributors may be
16 * used to endorse or promote products derived from this software without
17 * specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 /* This header file defines macros and functions for checking overflow in
34 * common integer arithmetic operations.
37 * - the "statement expression" GCC extension,
38 * - the "typeof" GCC extension,
39 * - the __builtin_add_overflow() and __builtin_mul_overflow() GCC/Clang
42 * If either built-in is unavailable, the corresponding macro replaces it with
43 * a call to an inline C function.
46 #ifndef NBDKIT_CHECKED_OVERFLOW_H
47 #define NBDKIT_CHECKED_OVERFLOW_H
49 #if !defined (__GNUC__) && !defined (__clang__)
50 #error "this file may need to be ported to your compiler"
56 #include "static-assert.h"
57 #include "unique-name.h"
59 /* Add "a" and "b", both of (possibly different) unsigned integer types, and
60 * store the sum in "*r", which must also have some unsigned integer type.
62 * Each macro argument is evaluated exactly once, as long as it does not have
63 * variably modified type.
65 * The macro evaluates to "false" if "*r" can represent the mathematical sum.
66 * Otherwise, the macro evaluates to "true", and the low order bits of the
67 * mathematical sum are stored to "*r".
69 #if HAVE_DECL___BUILTIN_ADD_OVERFLOW
70 #define ADD_OVERFLOW(a, b, r) ADD_OVERFLOW_BUILTIN ((a), (b), (r))
72 #define ADD_OVERFLOW(a, b, r) ADD_OVERFLOW_FALLBACK ((a), (b), (r))
75 /* Multiply "a" and "b", both of (possibly different) unsigned integer types,
76 * and store the product in "*r", which must also have some unsigned integer
79 * Each macro argument is evaluated exactly once, as long as it does not have
80 * variably modified type.
82 * The macro evaluates to "false" if "*r" can represent the mathematical
83 * product. Otherwise, the macro evaluates to "true", and the low order bits of
84 * the mathematical product are stored to "*r".
86 #if HAVE_DECL___BUILTIN_MUL_OVERFLOW
87 #define MUL_OVERFLOW(a, b, r) MUL_OVERFLOW_BUILTIN ((a), (b), (r))
89 #define MUL_OVERFLOW(a, b, r) MUL_OVERFLOW_FALLBACK ((a), (b), (r))
92 /* The ADD_OVERFLOW_BUILTIN and MUL_OVERFLOW_BUILTIN function-like macros
93 * enforce the unsignedness of all their operands even though the underlying
94 * compiler built-ins, __builtin_add_overflow() and __builtin_mul_overflow(),
95 * don't depend on that. The explanation is that the fallback implementation
96 * does depend on the unsignedness of all operands, and the codebase should
97 * seamlessly build regardless of the built-in vs. fallback choice.
99 * Each macro argument is evaluated exactly once, as long as it does not have
100 * variably modified type.
102 #if HAVE_DECL___BUILTIN_ADD_OVERFLOW
103 #define ADD_OVERFLOW_BUILTIN(a, b, r) \
105 STATIC_ASSERT_UNSIGNED_INT (a); \
106 STATIC_ASSERT_UNSIGNED_INT (b); \
107 STATIC_ASSERT_UNSIGNED_INT (*(r)); \
108 __builtin_add_overflow ((a), (b), (r)); \
112 #if HAVE_DECL___BUILTIN_MUL_OVERFLOW
113 #define MUL_OVERFLOW_BUILTIN(a, b, r) \
115 STATIC_ASSERT_UNSIGNED_INT (a); \
116 STATIC_ASSERT_UNSIGNED_INT (b); \
117 STATIC_ASSERT_UNSIGNED_INT (*(r)); \
118 __builtin_mul_overflow ((a), (b), (r)); \
122 /* The fallback macros call inline C functions. The unsignedness of all
123 * operands is enforced in order to keep the conversion to uintmax_t
124 * value-preserving, and to keep the conversion back from uintmax_t independent
125 * of the C language implementation.
127 * Each macro argument is evaluated exactly once, as long as it does not have
128 * variably modified type.
130 * The fallback macros and the inline C functions are defined regardless of
131 * HAVE_DECL___BUILTIN_ADD_OVERFLOW and HAVE_DECL___BUILTIN_MUL_OVERFLOW so
132 * that the test suite can always test the fallback.
134 #define ADD_OVERFLOW_FALLBACK(a, b, r) \
135 ADD_OVERFLOW_FALLBACK_1 ((a), (b), (r), \
136 NBDKIT_UNIQUE_NAME (_overflow), \
137 NBDKIT_UNIQUE_NAME (_tmp))
138 #define ADD_OVERFLOW_FALLBACK_1(a, b, r, overflow, tmp) \
143 STATIC_ASSERT_UNSIGNED_INT (a); \
144 STATIC_ASSERT_UNSIGNED_INT (b); \
145 STATIC_ASSERT_UNSIGNED_INT (*(r)); \
146 overflow = check_add_overflow ((a), (b), \
153 #define MUL_OVERFLOW_FALLBACK(a, b, r) \
154 MUL_OVERFLOW_FALLBACK_1 ((a), (b), (r), \
155 NBDKIT_UNIQUE_NAME (_overflow), \
156 NBDKIT_UNIQUE_NAME (_tmp))
157 #define MUL_OVERFLOW_FALLBACK_1(a, b, r, overflow, tmp) \
162 STATIC_ASSERT_UNSIGNED_INT (a); \
163 STATIC_ASSERT_UNSIGNED_INT (b); \
164 STATIC_ASSERT_UNSIGNED_INT (*(r)); \
165 overflow = check_mul_overflow ((a), (b), \
172 /* Assert, at compile time, that the expression "x" has some unsigned integer
175 * The expression "x" is not evaluated, unless it has variably modified type.
177 #define STATIC_ASSERT_UNSIGNED_INT(x) \
178 STATIC_ASSERT ((typeof (x))-1 > 0, _x_has_uint_type)
180 /* Assign the sum "a + b" to "*r", using uintmax_t modular arithmetic.
182 * Return true iff the addition overflows or the result exceeds "max".
185 check_add_overflow (uintmax_t a
, uintmax_t b
, uintmax_t max
, uintmax_t *r
)
190 in_range
= a
<= UINTMAX_MAX
- b
&& *r
<= max
;
194 /* Assign the product "a * b" to "*r", using uintmax_t modular arithmetic.
196 * Return true iff the multiplication overflows or the result exceeds "max".
199 check_mul_overflow (uintmax_t a
, uintmax_t b
, uintmax_t max
, uintmax_t *r
)
204 in_range
= b
== 0 || (a
<= UINTMAX_MAX
/ b
&& *r
<= max
);
208 #endif /* NBDKIT_CHECKED_OVERFLOW_H */