PostgreSQL Source Code  git master
int.h
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * int.h
4  * Overflow-aware integer math and integer comparison routines.
5  *
6  * The routines in this file are intended to be well defined C, without
7  * relying on compiler flags like -fwrapv.
8  *
9  * To reduce the overhead of these routines try to use compiler intrinsics
10  * where available. That's not that important for the 16, 32 bit cases, but
11  * the 64 bit cases can be considerably faster with intrinsics. In case no
12  * intrinsics are available 128 bit math is used where available.
13  *
14  * Copyright (c) 2017-2024, PostgreSQL Global Development Group
15  *
16  * src/include/common/int.h
17  *
18  *-------------------------------------------------------------------------
19  */
20 #ifndef COMMON_INT_H
21 #define COMMON_INT_H
22 
23 
24 /*---------
25  * The following guidelines apply to all the overflow routines:
26  *
27  * If the result overflows, return true, otherwise store the result into
28  * *result. The content of *result is implementation defined in case of
29  * overflow.
30  *
31  * bool pg_add_*_overflow(a, b, *result)
32  *
33  * Calculate a + b
34  *
35  * bool pg_sub_*_overflow(a, b, *result)
36  *
37  * Calculate a - b
38  *
39  * bool pg_mul_*_overflow(a, b, *result)
40  *
41  * Calculate a * b
42  *
43  * bool pg_neg_*_overflow(a, *result)
44  *
45  * Calculate -a
46  *
47  *
48  * In addition, this file contains:
49  *
50  * <unsigned int type> pg_abs_*(<signed int type> a)
51  *
52  * Calculate absolute value of a. Unlike the standard library abs()
53  * and labs() functions, the return type is unsigned, so the operation
54  * cannot overflow.
55  *---------
56  */
57 
58 /*------------------------------------------------------------------------
59  * Overflow routines for signed integers
60  *------------------------------------------------------------------------
61  */
62 
63 /*
64  * INT16
65  */
66 static inline bool
68 {
69 #if defined(HAVE__BUILTIN_OP_OVERFLOW)
70  return __builtin_add_overflow(a, b, result);
71 #else
72  int32 res = (int32) a + (int32) b;
73 
74  if (res > PG_INT16_MAX || res < PG_INT16_MIN)
75  {
76  *result = 0x5EED; /* to avoid spurious warnings */
77  return true;
78  }
79  *result = (int16) res;
80  return false;
81 #endif
82 }
83 
84 static inline bool
86 {
87 #if defined(HAVE__BUILTIN_OP_OVERFLOW)
88  return __builtin_sub_overflow(a, b, result);
89 #else
90  int32 res = (int32) a - (int32) b;
91 
92  if (res > PG_INT16_MAX || res < PG_INT16_MIN)
93  {
94  *result = 0x5EED; /* to avoid spurious warnings */
95  return true;
96  }
97  *result = (int16) res;
98  return false;
99 #endif
100 }
101 
102 static inline bool
104 {
105 #if defined(HAVE__BUILTIN_OP_OVERFLOW)
106  return __builtin_mul_overflow(a, b, result);
107 #else
108  int32 res = (int32) a * (int32) b;
109 
110  if (res > PG_INT16_MAX || res < PG_INT16_MIN)
111  {
112  *result = 0x5EED; /* to avoid spurious warnings */
113  return true;
114  }
115  *result = (int16) res;
116  return false;
117 #endif
118 }
119 
120 static inline uint16
122 {
123  /*
124  * This first widens the argument from int16 to int32 for use with abs().
125  * The result is then narrowed from int32 to uint16. This prevents any
126  * possibility of overflow.
127  */
128  return (uint16) abs((int32) a);
129 }
130 
131 /*
132  * INT32
133  */
134 static inline bool
136 {
137 #if defined(HAVE__BUILTIN_OP_OVERFLOW)
138  return __builtin_add_overflow(a, b, result);
139 #else
140  int64 res = (int64) a + (int64) b;
141 
142  if (res > PG_INT32_MAX || res < PG_INT32_MIN)
143  {
144  *result = 0x5EED; /* to avoid spurious warnings */
145  return true;
146  }
147  *result = (int32) res;
148  return false;
149 #endif
150 }
151 
152 static inline bool
154 {
155 #if defined(HAVE__BUILTIN_OP_OVERFLOW)
156  return __builtin_sub_overflow(a, b, result);
157 #else
158  int64 res = (int64) a - (int64) b;
159 
160  if (res > PG_INT32_MAX || res < PG_INT32_MIN)
161  {
162  *result = 0x5EED; /* to avoid spurious warnings */
163  return true;
164  }
165  *result = (int32) res;
166  return false;
167 #endif
168 }
169 
170 static inline bool
172 {
173 #if defined(HAVE__BUILTIN_OP_OVERFLOW)
174  return __builtin_mul_overflow(a, b, result);
175 #else
176  int64 res = (int64) a * (int64) b;
177 
178  if (res > PG_INT32_MAX || res < PG_INT32_MIN)
179  {
180  *result = 0x5EED; /* to avoid spurious warnings */
181  return true;
182  }
183  *result = (int32) res;
184  return false;
185 #endif
186 }
187 
188 static inline uint32
190 {
191  /*
192  * This first widens the argument from int32 to int64 for use with
193  * i64abs(). The result is then narrowed from int64 to uint32. This
194  * prevents any possibility of overflow.
195  */
196  return (uint32) i64abs((int64) a);
197 }
198 
199 /*
200  * INT64
201  */
202 static inline bool
203 pg_add_s64_overflow(int64 a, int64 b, int64 *result)
204 {
205 #if defined(HAVE__BUILTIN_OP_OVERFLOW)
206  return __builtin_add_overflow(a, b, result);
207 #elif defined(HAVE_INT128)
208  int128 res = (int128) a + (int128) b;
209 
210  if (res > PG_INT64_MAX || res < PG_INT64_MIN)
211  {
212  *result = 0x5EED; /* to avoid spurious warnings */
213  return true;
214  }
215  *result = (int64) res;
216  return false;
217 #else
218  if ((a > 0 && b > 0 && a > PG_INT64_MAX - b) ||
219  (a < 0 && b < 0 && a < PG_INT64_MIN - b))
220  {
221  *result = 0x5EED; /* to avoid spurious warnings */
222  return true;
223  }
224  *result = a + b;
225  return false;
226 #endif
227 }
228 
229 static inline bool
230 pg_sub_s64_overflow(int64 a, int64 b, int64 *result)
231 {
232 #if defined(HAVE__BUILTIN_OP_OVERFLOW)
233  return __builtin_sub_overflow(a, b, result);
234 #elif defined(HAVE_INT128)
235  int128 res = (int128) a - (int128) b;
236 
237  if (res > PG_INT64_MAX || res < PG_INT64_MIN)
238  {
239  *result = 0x5EED; /* to avoid spurious warnings */
240  return true;
241  }
242  *result = (int64) res;
243  return false;
244 #else
245  /*
246  * Note: overflow is also possible when a == 0 and b < 0 (specifically,
247  * when b == PG_INT64_MIN).
248  */
249  if ((a < 0 && b > 0 && a < PG_INT64_MIN + b) ||
250  (a >= 0 && b < 0 && a > PG_INT64_MAX + b))
251  {
252  *result = 0x5EED; /* to avoid spurious warnings */
253  return true;
254  }
255  *result = a - b;
256  return false;
257 #endif
258 }
259 
260 static inline bool
261 pg_mul_s64_overflow(int64 a, int64 b, int64 *result)
262 {
263 #if defined(HAVE__BUILTIN_OP_OVERFLOW)
264  return __builtin_mul_overflow(a, b, result);
265 #elif defined(HAVE_INT128)
266  int128 res = (int128) a * (int128) b;
267 
268  if (res > PG_INT64_MAX || res < PG_INT64_MIN)
269  {
270  *result = 0x5EED; /* to avoid spurious warnings */
271  return true;
272  }
273  *result = (int64) res;
274  return false;
275 #else
276  /*
277  * Overflow can only happen if at least one value is outside the range
278  * sqrt(min)..sqrt(max) so check that first as the division can be quite a
279  * bit more expensive than the multiplication.
280  *
281  * Multiplying by 0 or 1 can't overflow of course and checking for 0
282  * separately avoids any risk of dividing by 0. Be careful about dividing
283  * INT_MIN by -1 also, note reversing the a and b to ensure we're always
284  * dividing it by a positive value.
285  *
286  */
287  if ((a > PG_INT32_MAX || a < PG_INT32_MIN ||
288  b > PG_INT32_MAX || b < PG_INT32_MIN) &&
289  a != 0 && a != 1 && b != 0 && b != 1 &&
290  ((a > 0 && b > 0 && a > PG_INT64_MAX / b) ||
291  (a > 0 && b < 0 && b < PG_INT64_MIN / a) ||
292  (a < 0 && b > 0 && a < PG_INT64_MIN / b) ||
293  (a < 0 && b < 0 && a < PG_INT64_MAX / b)))
294  {
295  *result = 0x5EED; /* to avoid spurious warnings */
296  return true;
297  }
298  *result = a * b;
299  return false;
300 #endif
301 }
302 
303 static inline uint64
304 pg_abs_s64(int64 a)
305 {
306  if (unlikely(a == PG_INT64_MIN))
307  return (uint64) PG_INT64_MAX + 1;
308  return (uint64) i64abs(a);
309 }
310 
311 /*------------------------------------------------------------------------
312  * Overflow routines for unsigned integers
313  *------------------------------------------------------------------------
314  */
315 
316 /*
317  * UINT16
318  */
319 static inline bool
321 {
322 #if defined(HAVE__BUILTIN_OP_OVERFLOW)
323  return __builtin_add_overflow(a, b, result);
324 #else
325  uint16 res = a + b;
326 
327  if (res < a)
328  {
329  *result = 0x5EED; /* to avoid spurious warnings */
330  return true;
331  }
332  *result = res;
333  return false;
334 #endif
335 }
336 
337 static inline bool
339 {
340 #if defined(HAVE__BUILTIN_OP_OVERFLOW)
341  return __builtin_sub_overflow(a, b, result);
342 #else
343  if (b > a)
344  {
345  *result = 0x5EED; /* to avoid spurious warnings */
346  return true;
347  }
348  *result = a - b;
349  return false;
350 #endif
351 }
352 
353 static inline bool
355 {
356 #if defined(HAVE__BUILTIN_OP_OVERFLOW)
357  return __builtin_mul_overflow(a, b, result);
358 #else
359  uint32 res = (uint32) a * (uint32) b;
360 
361  if (res > PG_UINT16_MAX)
362  {
363  *result = 0x5EED; /* to avoid spurious warnings */
364  return true;
365  }
366  *result = (uint16) res;
367  return false;
368 #endif
369 }
370 
371 static inline bool
373 {
374 #if defined(HAVE__BUILTIN_OP_OVERFLOW)
375  return __builtin_sub_overflow(0, a, result);
376 #else
377  int32 res = -((int32) a);
378 
379  if (unlikely(res < PG_INT16_MIN))
380  {
381  *result = 0x5EED; /* to avoid spurious warnings */
382  return true;
383  }
384  *result = res;
385  return false;
386 #endif
387 }
388 
389 /*
390  * INT32
391  */
392 static inline bool
394 {
395 #if defined(HAVE__BUILTIN_OP_OVERFLOW)
396  return __builtin_add_overflow(a, b, result);
397 #else
398  uint32 res = a + b;
399 
400  if (res < a)
401  {
402  *result = 0x5EED; /* to avoid spurious warnings */
403  return true;
404  }
405  *result = res;
406  return false;
407 #endif
408 }
409 
410 static inline bool
412 {
413 #if defined(HAVE__BUILTIN_OP_OVERFLOW)
414  return __builtin_sub_overflow(a, b, result);
415 #else
416  if (b > a)
417  {
418  *result = 0x5EED; /* to avoid spurious warnings */
419  return true;
420  }
421  *result = a - b;
422  return false;
423 #endif
424 }
425 
426 static inline bool
428 {
429 #if defined(HAVE__BUILTIN_OP_OVERFLOW)
430  return __builtin_mul_overflow(a, b, result);
431 #else
432  uint64 res = (uint64) a * (uint64) b;
433 
434  if (res > PG_UINT32_MAX)
435  {
436  *result = 0x5EED; /* to avoid spurious warnings */
437  return true;
438  }
439  *result = (uint32) res;
440  return false;
441 #endif
442 }
443 
444 static inline bool
446 {
447 #if defined(HAVE__BUILTIN_OP_OVERFLOW)
448  return __builtin_sub_overflow(0, a, result);
449 #else
450  int64 res = -((int64) a);
451 
452  if (unlikely(res < PG_INT32_MIN))
453  {
454  *result = 0x5EED; /* to avoid spurious warnings */
455  return true;
456  }
457  *result = res;
458  return false;
459 #endif
460 }
461 
462 /*
463  * UINT64
464  */
465 static inline bool
466 pg_add_u64_overflow(uint64 a, uint64 b, uint64 *result)
467 {
468 #if defined(HAVE__BUILTIN_OP_OVERFLOW)
469  return __builtin_add_overflow(a, b, result);
470 #else
471  uint64 res = a + b;
472 
473  if (res < a)
474  {
475  *result = 0x5EED; /* to avoid spurious warnings */
476  return true;
477  }
478  *result = res;
479  return false;
480 #endif
481 }
482 
483 static inline bool
484 pg_sub_u64_overflow(uint64 a, uint64 b, uint64 *result)
485 {
486 #if defined(HAVE__BUILTIN_OP_OVERFLOW)
487  return __builtin_sub_overflow(a, b, result);
488 #else
489  if (b > a)
490  {
491  *result = 0x5EED; /* to avoid spurious warnings */
492  return true;
493  }
494  *result = a - b;
495  return false;
496 #endif
497 }
498 
499 static inline bool
500 pg_mul_u64_overflow(uint64 a, uint64 b, uint64 *result)
501 {
502 #if defined(HAVE__BUILTIN_OP_OVERFLOW)
503  return __builtin_mul_overflow(a, b, result);
504 #elif defined(HAVE_INT128)
505  uint128 res = (uint128) a * (uint128) b;
506 
507  if (res > PG_UINT64_MAX)
508  {
509  *result = 0x5EED; /* to avoid spurious warnings */
510  return true;
511  }
512  *result = (uint64) res;
513  return false;
514 #else
515  uint64 res = a * b;
516 
517  if (a != 0 && b != res / a)
518  {
519  *result = 0x5EED; /* to avoid spurious warnings */
520  return true;
521  }
522  *result = res;
523  return false;
524 #endif
525 }
526 
527 static inline bool
528 pg_neg_u64_overflow(uint64 a, int64 *result)
529 {
530 #if defined(HAVE__BUILTIN_OP_OVERFLOW)
531  return __builtin_sub_overflow(0, a, result);
532 #elif defined(HAVE_INT128)
533  int128 res = -((int128) a);
534 
535  if (unlikely(res < PG_INT64_MIN))
536  {
537  *result = 0x5EED; /* to avoid spurious warnings */
538  return true;
539  }
540  *result = res;
541  return false;
542 #else
543  if (unlikely(a > (uint64) PG_INT64_MAX + 1))
544  {
545  *result = 0x5EED; /* to avoid spurious warnings */
546  return true;
547  }
548  if (unlikely(a == (uint64) PG_INT64_MAX + 1))
549  *result = PG_INT64_MIN;
550  else
551  *result = -((int64) a);
552  return false;
553 #endif
554 }
555 
556 /*------------------------------------------------------------------------
557  *
558  * Comparison routines for integer types.
559  *
560  * These routines are primarily intended for use in qsort() comparator
561  * functions and therefore return a positive integer, 0, or a negative
562  * integer depending on whether "a" is greater than, equal to, or less
563  * than "b", respectively. These functions are written to be as efficient
564  * as possible without introducing overflow risks, thereby helping ensure
565  * the comparators that use them are transitive.
566  *
567  * Types with fewer than 32 bits are cast to signed integers and
568  * subtracted. Other types are compared using > and <, and the results of
569  * those comparisons (which are either (int) 0 or (int) 1 per the C
570  * standard) are subtracted.
571  *
572  * NB: If the comparator function is inlined, some compilers may produce
573  * worse code with these helper functions than with code with the
574  * following form:
575  *
576  * if (a < b)
577  * return -1;
578  * if (a > b)
579  * return 1;
580  * return 0;
581  *
582  *------------------------------------------------------------------------
583  */
584 
585 static inline int
587 {
588  return (int32) a - (int32) b;
589 }
590 
591 static inline int
593 {
594  return (int32) a - (int32) b;
595 }
596 
597 static inline int
599 {
600  return (a > b) - (a < b);
601 }
602 
603 static inline int
605 {
606  return (a > b) - (a < b);
607 }
608 
609 static inline int
610 pg_cmp_s64(int64 a, int64 b)
611 {
612  return (a > b) - (a < b);
613 }
614 
615 static inline int
616 pg_cmp_u64(uint64 a, uint64 b)
617 {
618  return (a > b) - (a < b);
619 }
620 
621 static inline int
622 pg_cmp_size(size_t a, size_t b)
623 {
624  return (a > b) - (a < b);
625 }
626 
627 #endif /* COMMON_INT_H */
unsigned short uint16
Definition: c.h:508
unsigned int uint32
Definition: c.h:509
#define PG_INT32_MAX
Definition: c.h:592
signed short int16
Definition: c.h:496
#define PG_UINT32_MAX
Definition: c.h:593
signed int int32
Definition: c.h:497
#define PG_INT16_MIN
Definition: c.h:588
#define PG_INT64_MAX
Definition: c.h:595
#define PG_INT64_MIN
Definition: c.h:594
#define unlikely(x)
Definition: c.h:314
#define PG_UINT16_MAX
Definition: c.h:590
#define PG_UINT64_MAX
Definition: c.h:596
#define PG_INT32_MIN
Definition: c.h:591
#define PG_INT16_MAX
Definition: c.h:589
#define i64abs(i)
Definition: c.h:1310
static bool pg_mul_s64_overflow(int64 a, int64 b, int64 *result)
Definition: int.h:261
static int pg_cmp_s16(int16 a, int16 b)
Definition: int.h:586
static uint64 pg_abs_s64(int64 a)
Definition: int.h:304
static bool pg_sub_u32_overflow(uint32 a, uint32 b, uint32 *result)
Definition: int.h:411
static int pg_cmp_u32(uint32 a, uint32 b)
Definition: int.h:604
static bool pg_add_u32_overflow(uint32 a, uint32 b, uint32 *result)
Definition: int.h:393
static bool pg_sub_s64_overflow(int64 a, int64 b, int64 *result)
Definition: int.h:230
static bool pg_add_u64_overflow(uint64 a, uint64 b, uint64 *result)
Definition: int.h:466
static int pg_cmp_u16(uint16 a, uint16 b)
Definition: int.h:592
static bool pg_neg_u32_overflow(uint32 a, int32 *result)
Definition: int.h:445
static bool pg_sub_s16_overflow(int16 a, int16 b, int16 *result)
Definition: int.h:85
static bool pg_neg_u16_overflow(uint16 a, int16 *result)
Definition: int.h:372
static bool pg_mul_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:171
static bool pg_mul_u16_overflow(uint16 a, uint16 b, uint16 *result)
Definition: int.h:354
static bool pg_mul_u32_overflow(uint32 a, uint32 b, uint32 *result)
Definition: int.h:427
static bool pg_mul_s16_overflow(int16 a, int16 b, int16 *result)
Definition: int.h:103
static int pg_cmp_s64(int64 a, int64 b)
Definition: int.h:610
static bool pg_mul_u64_overflow(uint64 a, uint64 b, uint64 *result)
Definition: int.h:500
static bool pg_sub_u16_overflow(uint16 a, uint16 b, uint16 *result)
Definition: int.h:338
static bool pg_add_u16_overflow(uint16 a, uint16 b, uint16 *result)
Definition: int.h:320
static bool pg_add_s16_overflow(int16 a, int16 b, int16 *result)
Definition: int.h:67
static uint32 pg_abs_s32(int32 a)
Definition: int.h:189
static int pg_cmp_s32(int32 a, int32 b)
Definition: int.h:598
static int pg_cmp_u64(uint64 a, uint64 b)
Definition: int.h:616
static int pg_cmp_size(size_t a, size_t b)
Definition: int.h:622
static uint16 pg_abs_s16(int16 a)
Definition: int.h:121
static bool pg_sub_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:153
static bool pg_neg_u64_overflow(uint64 a, int64 *result)
Definition: int.h:528
static bool pg_add_s64_overflow(int64 a, int64 b, int64 *result)
Definition: int.h:203
static bool pg_sub_u64_overflow(uint64 a, uint64 b, uint64 *result)
Definition: int.h:484
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:135
int b
Definition: isn.c:70
int a
Definition: isn.c:69