summaryrefslogtreecommitdiff
path: root/src/interfaces/ecpg
diff options
context:
space:
mode:
authorNathan Bossart2024-08-15 20:47:31 +0000
committerNathan Bossart2024-08-15 20:47:31 +0000
commit9e9a2b7031f64e49fcaf28f21a4e70eb1212165f (patch)
treee7abac509a29b705ad76d8d5123894fe3e1bf3ba /src/interfaces/ecpg
parentad89d71978429c61647ae57174a61deb192bd51c (diff)
Remove dependence on -fwrapv semantics in a few places.
This commit attempts to update a few places, such as the money, numeric, and timestamp types, to no longer rely on signed integer wrapping for correctness. This is intended to move us closer towards removing -fwrapv, which may enable some compiler optimizations. However, there is presently no plan to actually remove that compiler option in the near future. Besides using some of the existing overflow-aware routines in int.h, this commit introduces and makes use of some new ones. Specifically, it adds functions that accept a signed integer and return its absolute value as an unsigned integer with the same width (e.g., pg_abs_s64()). It also adds functions that accept an unsigned integer, store the result of negating that integer in a signed integer with the same width, and return whether the negation overflowed (e.g., pg_neg_u64_overflow()). Finally, this commit adds a couple of tests for timestamps near POSTGRES_EPOCH_JDATE. Author: Joseph Koshakow Reviewed-by: Tom Lane, Heikki Linnakangas, Jian He Discussion: https://postgr.es/m/CAAvxfHdBPOyEGS7s%2Bxf4iaW0-cgiq25jpYdWBqQqvLtLe_t6tw%40mail.gmail.com
Diffstat (limited to 'src/interfaces/ecpg')
-rw-r--r--src/interfaces/ecpg/pgtypeslib/timestamp.c11
1 files changed, 3 insertions, 8 deletions
diff --git a/src/interfaces/ecpg/pgtypeslib/timestamp.c b/src/interfaces/ecpg/pgtypeslib/timestamp.c
index f1b143fbd2e..402fae6da67 100644
--- a/src/interfaces/ecpg/pgtypeslib/timestamp.c
+++ b/src/interfaces/ecpg/pgtypeslib/timestamp.c
@@ -11,6 +11,7 @@
#error -ffast-math is known to break this code
#endif
+#include "common/int.h"
#include "dt.h"
#include "pgtypes_date.h"
#include "pgtypes_timestamp.h"
@@ -48,14 +49,8 @@ tm2timestamp(struct tm *tm, fsec_t fsec, int *tzp, timestamp * result)
dDate = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1);
time = time2t(tm->tm_hour, tm->tm_min, tm->tm_sec, fsec);
- *result = (dDate * USECS_PER_DAY) + time;
- /* check for major overflow */
- if ((*result - time) / USECS_PER_DAY != dDate)
- return -1;
- /* check for just-barely overflow (okay except time-of-day wraps) */
- /* caution: we want to allow 1999-12-31 24:00:00 */
- if ((*result < 0 && dDate > 0) ||
- (*result > 0 && dDate < -1))
+ if (unlikely(pg_mul_s64_overflow(dDate, USECS_PER_DAY, result) ||
+ pg_add_s64_overflow(*result, time, result)))
return -1;
if (tzp != NULL)
*result = dt2local(*result, -(*tzp));