Macaulay2 Engine
Loading...
Searching...
No Matches
overflow.hpp
Go to the documentation of this file.
1#ifndef _overflow_h_
2#define _overflow_h_
3
34
35#ifdef SIGNAL_ERROR
36#error SIGNAL_ERROR
37#endif
38
39// methods for detecting arithmetic overflows
40
41#include "exceptions.hpp"
42#include <cassert>
43#include <M2/config.h>
44
45#if HAVE_STDINT_H
46#if !defined(__STDC_LIMIT_MACROS)
47#define __STDC_LIMIT_MACROS
48#endif
49#include <stdint.h>
50#elif HAVE_INTTYPES_H
51#include <inttypes.h>
52#else
53#error integer type definitions not available
54#endif
55
56#if defined(__has_builtin)
57#define HAS_BUILTIN(x) __has_builtin(x)
58#else
59#define HAS_BUILTIN(x) 0
60#endif
61
62#if defined(__GNUC__) || HAS_BUILTIN(__builtin_expect)
63#define expect_false(x) (__builtin_expect(x, 0))
64#define expect_true(x) (__builtin_expect(x, 1))
65#else
66#define expect_false(x) (x)
67#define expect_true(x) (x)
68#endif
69
70namespace safe {
71
72void ov(const char *msg);
73
74static inline int32_t fits_7(int32_t x, const char *msg)
75{
76 if
77 expect_false(((uint32_t)x & ~0x7f) != 0) ov(msg);
78 return x;
79}
80static inline int32_t fits_15(int32_t x, const char *msg)
81{
82 if
83 expect_false(((uint32_t)x & ~0x7fff) != 0) ov(msg);
84 return x;
85}
86static inline int32_t fits_31(int32_t x, const char *msg)
87{
88 if
89 expect_false(x < 0) ov(msg);
90 return x;
91}
92
93static inline int32_t fits_7(int32_t x)
94{
95 return fits_7(x, "monomial exponent overflow: fits_7");
96}
97static inline int32_t fits_15(int32_t x)
98{
99 return fits_15(x, "monomial exponent overflow: fits_15");
100}
101static inline int32_t fits_31(int32_t x)
102{
103 return fits_31(x, "monomial exponent overflow: fits_31");
104}
105
106static inline int32_t over_1(int32_t x) { return x < 0; }
107static inline int32_t over_2(int32_t x)
108{
109 return (0x80008000u & (uint32_t)x) != 0;
110}
111static inline int32_t over_4(int32_t x)
112{
113 return (0x80808080u & (uint32_t)x) != 0;
114}
115
116static inline int32_t add(int32_t x, int32_t y, const char *msg)
117{
118 int32_t z = (uint32_t)x + (uint32_t)y;
119 if
120 expect_false((int32_t)((uint32_t)x ^ (uint32_t)z) < 0 &&
121 (int32_t)((uint32_t)x ^ (uint32_t)y) >= 0) ov(msg);
122 return z;
123}
124
125static inline int32_t add(int32_t x, int32_t y)
126{
127 return add(x, y, "monomial exponent overflow: int32_t + int32_t");
128}
129
130static inline int32_t add_to(int32_t &x, int32_t y, const char *msg)
131{
132 int32_t z = (uint32_t)x + (uint32_t)y;
133 if
134 expect_false((int32_t)((uint32_t)x ^ (uint32_t)z) < 0 &&
135 (int32_t)((uint32_t)x ^ (uint32_t)y) >= 0) ov(msg);
136 return x = z;
137}
138
139static inline int32_t add_to(int32_t &x, int32_t y)
140{
141 return add_to(x, y, "monomial exponent overflow: int32_t + int32_t");
142}
143
144static inline int32_t sub(int32_t x, int32_t y, const char *msg)
145{
146 int32_t z = (uint32_t)x - (uint32_t)y;
147 if
148 expect_false((int32_t)((uint32_t)x ^ (uint32_t)z) < 0 &&
149 (int32_t)((uint32_t)x ^ (uint32_t)y) < 0) ov(msg);
150 return z;
151}
152
153static inline int32_t sub(int32_t x, int32_t y)
154{
155 return sub(x, y, "monomial exponent overflow: int32_t - int32_t");
156}
157
158static inline int32_t sub_from(int32_t &x, int32_t y, const char *msg)
159{
160 int32_t z = (uint32_t)x - (uint32_t)y;
161 if
162 expect_false((int32_t)((uint32_t)x ^ (uint32_t)z) < 0 &&
163 (int32_t)((uint32_t)x ^ (uint32_t)y) < 0) ov(msg);
164 return x = z;
165}
166
167static inline int32_t sub_from(int32_t &x, int32_t y)
168{
169 return sub_from(x, y, "monomial exponent overflow: int32_t - int32_t");
170}
171
172static inline int32_t sub_pos(int32_t x, int32_t y, const char *msg)
173{
174 if (x <= y) return 0;
175 int32_t z = (uint32_t)x - (uint32_t)y;
176 if
177 expect_false(z < 0) ov(msg);
178 return z;
179}
180static inline int32_t sub_pos(int32_t x, int32_t y)
181{
182 return sub_pos(x, y, "monomial exponent overflow: int32_t - int32_t [pos]");
183}
184
185static inline int32_t minus(int32_t x, const char *msg)
186{
187 int32_t z = -(uint32_t)x;
188 if
189 expect_false(z == x && x != 0) ov(msg);
190 return z;
191}
192static inline int32_t minus(int32_t x)
193{
194 return minus(x, "monomial exponent overflow: - int32_t");
195}
196
197static inline int32_t pos_add(int32_t x, int32_t y, const char *msg)
198{
199 assert(!over_1(x) && !over_1(y));
200 int32_t z = (uint32_t)x + (uint32_t)y;
201 if
202 expect_false(over_1(z)) ov(msg);
203 return z;
204}
205static inline int32_t pos_add(int32_t x, int32_t y)
206{
207 return pos_add(x, y, "monomial exponent overflow: pos int32_t + pos int32_t");
208}
209static inline int32_t pos_add_2(int32_t x, int32_t y, const char *msg)
210{
211 assert(!over_2(x) && !over_2(y));
212 int32_t z = (uint32_t)x + (uint32_t)y;
213 if
214 expect_false(over_2(z)) ov(msg);
215 return z;
216}
217static inline int32_t pos_add_2(int32_t x, int32_t y)
218{
219 return pos_add_2(
220 x, y, "monomial exponent overflow: pos int32_t + pos int32_t, packed 2");
221}
222static inline int32_t pos_add_4(int32_t x, int32_t y, const char *msg)
223{
224 assert(!over_4(x) && !over_4(y));
225 int32_t z = (uint32_t)x + (uint32_t)y;
226 if
227 expect_false(over_4(z)) ov(msg);
228 return z;
229}
230static inline int32_t pos_add_4(int32_t x, int32_t y)
231{
232 return pos_add_4(
233 x, y, "monomial exponent overflow: pos int32_t + pos int32_t, packed 4");
234}
235
236static inline int32_t mult(int32_t x, int32_t y, const char *msg)
237{
238 int64_t z = (int64_t)x * y;
239 int32_t w = (int32_t)z;
240 if
241 expect_false(z != (int64_t)w) ov(msg);
242 return w;
243}
244static inline int32_t mult(int32_t x, int32_t y)
245{
246 return mult(x, y, "monomial exponent overflow: int32_t * int32_t (mult)");
247}
248
249static inline int32_t mult_by(int32_t &x, int32_t y, const char *msg)
250{
251 int64_t z = (int64_t)x * y;
252 int32_t w = (int32_t)z;
253 if
254 expect_false(z != (int64_t)w) ov(msg);
255 return x = w;
256}
257static inline int32_t mult_by(int32_t &x, int32_t y)
258{
259 return mult_by(
260 x, y, "monomial exponent overflow: int32_t * int32_t (mult_by)");
261}
262
263static inline int32_t div(int32_t x, int32_t y, const char *msg)
264{
265 if
266 expect_false((uint32_t)x == -(uint32_t)x && x < 0 && y == -1) ov(msg);
267 return x / y;
268}
269static inline int32_t div(int32_t x, int32_t y)
270{
271 return div(x, y, "monomial exponent overflow: int32 / int32");
272}
273
274static inline int32_t div_by(int32_t &x, int32_t y, const char *msg)
275{
276 if
277 expect_false((uint32_t)x == -(uint32_t)x && x < 0 && y == -1) ov(msg);
278 return x /= y;
279}
280static inline int32_t div_by(int32_t &x, int32_t y)
281{
282 return div_by(x, y, "monomial exponent overflow: int32 / int32");
283}
284}
285
286#endif
287
288// Local Variables:
289// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
290// indent-tabs-mode: nil
291// End:
namespace exc — internal C++ exception types and the TRY / CATCH macro pair.
static int32_t fits_31(int32_t x, const char *msg)
Definition overflow.hpp:86
static int32_t mult(int32_t x, int32_t y, const char *msg)
Definition overflow.hpp:236
static int32_t div_by(int32_t &x, int32_t y, const char *msg)
Definition overflow.hpp:274
static int32_t over_4(int32_t x)
Definition overflow.hpp:111
static int32_t mult_by(int32_t &x, int32_t y, const char *msg)
Definition overflow.hpp:249
static int32_t sub_from(int32_t &x, int32_t y, const char *msg)
Definition overflow.hpp:158
static int32_t pos_add(int32_t x, int32_t y, const char *msg)
Definition overflow.hpp:197
static int32_t add(int32_t x, int32_t y, const char *msg)
Definition overflow.hpp:116
static int32_t div(int32_t x, int32_t y, const char *msg)
Definition overflow.hpp:263
static int32_t over_2(int32_t x)
Definition overflow.hpp:107
static int32_t pos_add_4(int32_t x, int32_t y, const char *msg)
Definition overflow.hpp:222
static int32_t fits_7(int32_t x, const char *msg)
Definition overflow.hpp:74
static int32_t add_to(int32_t &x, int32_t y, const char *msg)
Definition overflow.hpp:130
static int32_t sub(int32_t x, int32_t y, const char *msg)
Definition overflow.hpp:144
void ov(const char *msg)
Definition overflow.cpp:5
static int32_t pos_add_2(int32_t x, int32_t y, const char *msg)
Definition overflow.hpp:209
static int32_t fits_15(int32_t x, const char *msg)
Definition overflow.hpp:80
static int32_t over_1(int32_t x)
Definition overflow.hpp:106
static int32_t sub_pos(int32_t x, int32_t y, const char *msg)
Definition overflow.hpp:172
static int32_t minus(int32_t x, const char *msg)
Definition overflow.hpp:185
volatile int x
#define expect_false(x)
Definition overflow.hpp:66