20
20
#ifndef COMMON_INT_H
21
21
#define COMMON_INT_H
22
22
23
- /*
24
- * If a + b overflows, return true, otherwise store the result of a + b into
25
- * *result. The content of *result is implementation defined in case of
23
+
24
+ /*---------
25
+ * The following guidelines apply to all the routines:
26
+ * - If a + b overflows, return true, otherwise store the result of a + b
27
+ * into *result. The content of *result is implementation defined in case of
28
+ * overflow.
29
+ * - If a - b overflows, return true, otherwise store the result of a - b
30
+ * into *result. The content of *result is implementation defined in case of
26
31
* overflow.
32
+ * - If a * b overflows, return true, otherwise store the result of a * b
33
+ * into *result. The content of *result is implementation defined in case of
34
+ * overflow.
35
+ *---------
36
+ */
37
+
38
+ /*------------------------------------------------------------------------
39
+ * Overflow routines for signed integers
40
+ *------------------------------------------------------------------------
41
+ */
42
+
43
+ /*
44
+ * INT16
27
45
*/
28
46
static inline bool
29
47
pg_add_s16_overflow (int16 a , int16 b , int16 * result )
@@ -43,11 +61,6 @@ pg_add_s16_overflow(int16 a, int16 b, int16 *result)
43
61
#endif
44
62
}
45
63
46
- /*
47
- * If a - b overflows, return true, otherwise store the result of a - b into
48
- * *result. The content of *result is implementation defined in case of
49
- * overflow.
50
- */
51
64
static inline bool
52
65
pg_sub_s16_overflow (int16 a , int16 b , int16 * result )
53
66
{
@@ -66,11 +79,6 @@ pg_sub_s16_overflow(int16 a, int16 b, int16 *result)
66
79
#endif
67
80
}
68
81
69
- /*
70
- * If a * b overflows, return true, otherwise store the result of a * b into
71
- * *result. The content of *result is implementation defined in case of
72
- * overflow.
73
- */
74
82
static inline bool
75
83
pg_mul_s16_overflow (int16 a , int16 b , int16 * result )
76
84
{
@@ -90,9 +98,7 @@ pg_mul_s16_overflow(int16 a, int16 b, int16 *result)
90
98
}
91
99
92
100
/*
93
- * If a + b overflows, return true, otherwise store the result of a + b into
94
- * *result. The content of *result is implementation defined in case of
95
- * overflow.
101
+ * INT32
96
102
*/
97
103
static inline bool
98
104
pg_add_s32_overflow (int32 a , int32 b , int32 * result )
@@ -112,11 +118,6 @@ pg_add_s32_overflow(int32 a, int32 b, int32 *result)
112
118
#endif
113
119
}
114
120
115
- /*
116
- * If a - b overflows, return true, otherwise store the result of a - b into
117
- * *result. The content of *result is implementation defined in case of
118
- * overflow.
119
- */
120
121
static inline bool
121
122
pg_sub_s32_overflow (int32 a , int32 b , int32 * result )
122
123
{
@@ -135,11 +136,6 @@ pg_sub_s32_overflow(int32 a, int32 b, int32 *result)
135
136
#endif
136
137
}
137
138
138
- /*
139
- * If a * b overflows, return true, otherwise store the result of a * b into
140
- * *result. The content of *result is implementation defined in case of
141
- * overflow.
142
- */
143
139
static inline bool
144
140
pg_mul_s32_overflow (int32 a , int32 b , int32 * result )
145
141
{
@@ -159,9 +155,7 @@ pg_mul_s32_overflow(int32 a, int32 b, int32 *result)
159
155
}
160
156
161
157
/*
162
- * If a + b overflows, return true, otherwise store the result of a + b into
163
- * *result. The content of *result is implementation defined in case of
164
- * overflow.
158
+ * INT64
165
159
*/
166
160
static inline bool
167
161
pg_add_s64_overflow (int64 a , int64 b , int64 * result )
@@ -190,11 +184,6 @@ pg_add_s64_overflow(int64 a, int64 b, int64 *result)
190
184
#endif
191
185
}
192
186
193
- /*
194
- * If a - b overflows, return true, otherwise store the result of a - b into
195
- * *result. The content of *result is implementation defined in case of
196
- * overflow.
197
- */
198
187
static inline bool
199
188
pg_sub_s64_overflow (int64 a , int64 b , int64 * result )
200
189
{
@@ -222,11 +211,6 @@ pg_sub_s64_overflow(int64 a, int64 b, int64 *result)
222
211
#endif
223
212
}
224
213
225
- /*
226
- * If a * b overflows, return true, otherwise store the result of a * b into
227
- * *result. The content of *result is implementation defined in case of
228
- * overflow.
229
- */
230
214
static inline bool
231
215
pg_mul_s64_overflow (int64 a , int64 b , int64 * result )
232
216
{
@@ -270,4 +254,184 @@ pg_mul_s64_overflow(int64 a, int64 b, int64 *result)
270
254
#endif
271
255
}
272
256
257
+ /*------------------------------------------------------------------------
258
+ * Overflow routines for unsigned integers
259
+ *------------------------------------------------------------------------
260
+ */
261
+
262
+ /*
263
+ * UINT16
264
+ */
265
+ static inline bool
266
+ pg_add_u16_overflow (uint16 a , uint16 b , uint16 * result )
267
+ {
268
+ #if defined(HAVE__BUILTIN_OP_OVERFLOW )
269
+ return __builtin_add_overflow (a , b , result );
270
+ #else
271
+ uint16 res = a + b ;
272
+
273
+ if (res < a )
274
+ {
275
+ * result = 0x5EED ; /* to avoid spurious warnings */
276
+ return true;
277
+ }
278
+ * result = res ;
279
+ return false;
280
+ #endif
281
+ }
282
+
283
+ static inline bool
284
+ pg_sub_u16_overflow (uint16 a , uint16 b , uint16 * result )
285
+ {
286
+ #if defined(HAVE__BUILTIN_OP_OVERFLOW )
287
+ return __builtin_sub_overflow (a , b , result );
288
+ #else
289
+ if (b > a )
290
+ {
291
+ * result = 0x5EED ; /* to avoid spurious warnings */
292
+ return true;
293
+ }
294
+ * result = a - b ;
295
+ return false;
296
+ #endif
297
+ }
298
+
299
+ static inline bool
300
+ pg_mul_u16_overflow (uint16 a , uint16 b , uint16 * result )
301
+ {
302
+ #if defined(HAVE__BUILTIN_OP_OVERFLOW )
303
+ return __builtin_mul_overflow (a , b , result );
304
+ #else
305
+ uint32 res = (uint32 ) a * (uint32 ) b ;
306
+
307
+ if (res > PG_UINT16_MAX )
308
+ {
309
+ * result = 0x5EED ; /* to avoid spurious warnings */
310
+ return true;
311
+ }
312
+ * result = (uint16 ) res ;
313
+ return false;
314
+ #endif
315
+ }
316
+
317
+ /*
318
+ * INT32
319
+ */
320
+ static inline bool
321
+ pg_add_u32_overflow (uint32 a , uint32 b , uint32 * result )
322
+ {
323
+ #if defined(HAVE__BUILTIN_OP_OVERFLOW )
324
+ return __builtin_add_overflow (a , b , result );
325
+ #else
326
+ uint32 res = a + b ;
327
+
328
+ if (res < a )
329
+ {
330
+ * result = 0x5EED ; /* to avoid spurious warnings */
331
+ return true;
332
+ }
333
+ * result = res ;
334
+ return false;
335
+ #endif
336
+ }
337
+
338
+ static inline bool
339
+ pg_sub_u32_overflow (uint32 a , uint32 b , uint32 * result )
340
+ {
341
+ #if defined(HAVE__BUILTIN_OP_OVERFLOW )
342
+ return __builtin_sub_overflow (a , b , result );
343
+ #else
344
+ if (b > a )
345
+ {
346
+ * result = 0x5EED ; /* to avoid spurious warnings */
347
+ return true;
348
+ }
349
+ * result = a - b ;
350
+ return false;
351
+ #endif
352
+ }
353
+
354
+ static inline bool
355
+ pg_mul_u32_overflow (uint32 a , uint32 b , uint32 * result )
356
+ {
357
+ #if defined(HAVE__BUILTIN_OP_OVERFLOW )
358
+ return __builtin_mul_overflow (a , b , result );
359
+ #else
360
+ uint64 res = (uint64 ) a * (uint64 ) b ;
361
+
362
+ if (res > PG_UINT32_MAX )
363
+ {
364
+ * result = 0x5EED ; /* to avoid spurious warnings */
365
+ return true;
366
+ }
367
+ * result = (uint32 ) res ;
368
+ return false;
369
+ #endif
370
+ }
371
+
372
+ /*
373
+ * UINT64
374
+ */
375
+ static inline bool
376
+ pg_add_u64_overflow (uint64 a , uint64 b , uint64 * result )
377
+ {
378
+ #if defined(HAVE__BUILTIN_OP_OVERFLOW )
379
+ return __builtin_add_overflow (a , b , result );
380
+ #else
381
+ uint64 res = a + b ;
382
+
383
+ if (res < a )
384
+ {
385
+ * result = 0x5EED ; /* to avoid spurious warnings */
386
+ return true;
387
+ }
388
+ * result = res ;
389
+ return false;
390
+ #endif
391
+ }
392
+
393
+ static inline bool
394
+ pg_sub_u64_overflow (uint64 a , uint64 b , uint64 * result )
395
+ {
396
+ #if defined(HAVE__BUILTIN_OP_OVERFLOW )
397
+ return __builtin_sub_overflow (a , b , result );
398
+ #else
399
+ if (b > a )
400
+ {
401
+ * result = 0x5EED ; /* to avoid spurious warnings */
402
+ return true;
403
+ }
404
+ * result = a - b ;
405
+ return false;
406
+ #endif
407
+ }
408
+
409
+ static inline bool
410
+ pg_mul_u64_overflow (uint64 a , uint64 b , uint64 * result )
411
+ {
412
+ #if defined(HAVE__BUILTIN_OP_OVERFLOW )
413
+ return __builtin_mul_overflow (a , b , result );
414
+ #elif defined(HAVE_INT128 )
415
+ uint128 res = (uint128 ) a * (uint128 ) b ;
416
+
417
+ if (res > PG_UINT64_MAX )
418
+ {
419
+ * result = 0x5EED ; /* to avoid spurious warnings */
420
+ return true;
421
+ }
422
+ * result = (uint64 ) res ;
423
+ return false;
424
+ #else
425
+ uint64 res = a * b ;
426
+
427
+ if (a != 0 && b != res / a )
428
+ {
429
+ * result = 0x5EED ; /* to avoid spurious warnings */
430
+ return true;
431
+ }
432
+ * result = res ;
433
+ return false;
434
+ #endif
435
+ }
436
+
273
437
#endif /* COMMON_INT_H */
0 commit comments