2020#ifndef COMMON_INT_H
2121#define COMMON_INT_H
2222
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
2631 * 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
2745 */
2846static inline bool
2947pg_add_s16_overflow (int16 a , int16 b , int16 * result )
@@ -43,11 +61,6 @@ pg_add_s16_overflow(int16 a, int16 b, int16 *result)
4361#endif
4462}
4563
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- */
5164static inline bool
5265pg_sub_s16_overflow (int16 a , int16 b , int16 * result )
5366{
@@ -66,11 +79,6 @@ pg_sub_s16_overflow(int16 a, int16 b, int16 *result)
6679#endif
6780}
6881
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- */
7482static inline bool
7583pg_mul_s16_overflow (int16 a , int16 b , int16 * result )
7684{
@@ -90,9 +98,7 @@ pg_mul_s16_overflow(int16 a, int16 b, int16 *result)
9098}
9199
92100/*
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
96102 */
97103static inline bool
98104pg_add_s32_overflow (int32 a , int32 b , int32 * result )
@@ -112,11 +118,6 @@ pg_add_s32_overflow(int32 a, int32 b, int32 *result)
112118#endif
113119}
114120
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- */
120121static inline bool
121122pg_sub_s32_overflow (int32 a , int32 b , int32 * result )
122123{
@@ -135,11 +136,6 @@ pg_sub_s32_overflow(int32 a, int32 b, int32 *result)
135136#endif
136137}
137138
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- */
143139static inline bool
144140pg_mul_s32_overflow (int32 a , int32 b , int32 * result )
145141{
@@ -159,9 +155,7 @@ pg_mul_s32_overflow(int32 a, int32 b, int32 *result)
159155}
160156
161157/*
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
165159 */
166160static inline bool
167161pg_add_s64_overflow (int64 a , int64 b , int64 * result )
@@ -190,11 +184,6 @@ pg_add_s64_overflow(int64 a, int64 b, int64 *result)
190184#endif
191185}
192186
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- */
198187static inline bool
199188pg_sub_s64_overflow (int64 a , int64 b , int64 * result )
200189{
@@ -222,11 +211,6 @@ pg_sub_s64_overflow(int64 a, int64 b, int64 *result)
222211#endif
223212}
224213
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- */
230214static inline bool
231215pg_mul_s64_overflow (int64 a , int64 b , int64 * result )
232216{
@@ -270,4 +254,184 @@ pg_mul_s64_overflow(int64 a, int64 b, int64 *result)
270254#endif
271255}
272256
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+
273437#endif /* COMMON_INT_H */
0 commit comments