summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndres Freund2018-02-14 22:17:28 +0000
committerAndres Freund2018-02-14 22:23:57 +0000
commit6d7dc5350042697bbb141a7362649db7fa67bd55 (patch)
treeefb1ae413553a0e22c758dd4ea494ec3c6281f8a
parent9a725f7b5cb7e8c8894ef121b49eff9c265245c8 (diff)
Return implementation defined value if pg_$op_s$bit_overflow overflows.
Some older compilers otherwise sometimes complain about undefined values, even though the return value should not be used in the overflow case. We assume that any decent compiler will optimize away the unnecessary assignment in performance critical cases. We do not want to restrain the returned value to a specific value, e.g. 0 or the wrapped-around value, because some fast ways to implement overflow detecting math do not easily allow for that (e.g. msvc intrinsics). As the function documentation already documents the returned value in case of intrinsics to be implementation defined, no documentation has to be updated. Per complaint from Tom Lane and his buildfarm member prairiedog. Author: Andres Freund Discussion: https://postgr.es/m/[email protected]
-rw-r--r--src/include/common/int.h34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/include/common/int.h b/src/include/common/int.h
index feb84102b4..82e38d4b7b 100644
--- a/src/include/common/int.h
+++ b/src/include/common/int.h
@@ -34,7 +34,10 @@ pg_add_s16_overflow(int16 a, int16 b, int16 *result)
int32 res = (int32) a + (int32) b;
if (res > PG_INT16_MAX || res < PG_INT16_MIN)
+ {
+ *result = 0x5EED; /* to avoid spurious warnings */
return true;
+ }
*result = (int16) res;
return false;
#endif
@@ -54,7 +57,10 @@ pg_sub_s16_overflow(int16 a, int16 b, int16 *result)
int32 res = (int32) a - (int32) b;
if (res > PG_INT16_MAX || res < PG_INT16_MIN)
+ {
+ *result = 0x5EED; /* to avoid spurious warnings */
return true;
+ }
*result = (int16) res;
return false;
#endif
@@ -74,7 +80,10 @@ pg_mul_s16_overflow(int16 a, int16 b, int16 *result)
int32 res = (int32) a * (int32) b;
if (res > PG_INT16_MAX || res < PG_INT16_MIN)
+ {
+ *result = 0x5EED; /* to avoid spurious warnings */
return true;
+ }
*result = (int16) res;
return false;
#endif
@@ -94,7 +103,10 @@ pg_add_s32_overflow(int32 a, int32 b, int32 *result)
int64 res = (int64) a + (int64) b;
if (res > PG_INT32_MAX || res < PG_INT32_MIN)
+ {
+ *result = 0x5EED; /* to avoid spurious warnings */
return true;
+ }
*result = (int32) res;
return false;
#endif
@@ -114,7 +126,10 @@ pg_sub_s32_overflow(int32 a, int32 b, int32 *result)
int64 res = (int64) a - (int64) b;
if (res > PG_INT32_MAX || res < PG_INT32_MIN)
+ {
+ *result = 0x5EED; /* to avoid spurious warnings */
return true;
+ }
*result = (int32) res;
return false;
#endif
@@ -134,7 +149,10 @@ pg_mul_s32_overflow(int32 a, int32 b, int32 *result)
int64 res = (int64) a * (int64) b;
if (res > PG_INT32_MAX || res < PG_INT32_MIN)
+ {
+ *result = 0x5EED; /* to avoid spurious warnings */
return true;
+ }
*result = (int32) res;
return false;
#endif
@@ -154,13 +172,19 @@ pg_add_s64_overflow(int64 a, int64 b, int64 *result)
int128 res = (int128) a + (int128) b;
if (res > PG_INT64_MAX || res < PG_INT64_MIN)
+ {
+ *result = 0x5EED; /* to avoid spurious warnings */
return true;
+ }
*result = (int64) res;
return false;
#else
if ((a > 0 && b > 0 && a > PG_INT64_MAX - b) ||
(a < 0 && b < 0 && a < PG_INT64_MIN - b))
+ {
+ *result = 0x5EED; /* to avoid spurious warnings */
return true;
+ }
*result = a + b;
return false;
#endif
@@ -180,13 +204,19 @@ pg_sub_s64_overflow(int64 a, int64 b, int64 *result)
int128 res = (int128) a - (int128) b;
if (res > PG_INT64_MAX || res < PG_INT64_MIN)
+ {
+ *result = 0x5EED; /* to avoid spurious warnings */
return true;
+ }
*result = (int64) res;
return false;
#else
if ((a < 0 && b > 0 && a < PG_INT64_MIN + b) ||
(a > 0 && b < 0 && a > PG_INT64_MAX + b))
+ {
+ *result = 0x5EED; /* to avoid spurious warnings */
return true;
+ }
*result = a - b;
return false;
#endif
@@ -206,7 +236,10 @@ pg_mul_s64_overflow(int64 a, int64 b, int64 *result)
int128 res = (int128) a * (int128) b;
if (res > PG_INT64_MAX || res < PG_INT64_MIN)
+ {
+ *result = 0x5EED; /* to avoid spurious warnings */
return true;
+ }
*result = (int64) res;
return false;
#else
@@ -229,6 +262,7 @@ pg_mul_s64_overflow(int64 a, int64 b, int64 *result)
(a < 0 && b > 0 && a < PG_INT64_MIN / b) ||
(a < 0 && b < 0 && a < PG_INT64_MAX / b)))
{
+ *result = 0x5EED; /* to avoid spurious warnings */
return true;
}
*result = a * b;