mirror of
https://github.com/postgres/postgres.git
synced 2025-08-31 17:02:12 +03:00
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
This commit is contained in:
@@ -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));
|
||||
|
Reference in New Issue
Block a user