[tz] [PROPOSED] Try to check longstanding padding assumptions
Paul Eggert
eggert at cs.ucla.edu
Thu Dec 8 02:57:54 UTC 2022
This is helpful only when porting to oddball platforms in some
situations where time_t is signed and has padding bits. (Even C23
allows these platforms.) Formerly tzcode would silently have
undefined runtime behavior on such platforms; with this patch, there
is likely a compile-time diagnostic instead.
* private.h (static_assert): New macro, defined for pre-C23 compilers.
(SIGNED_PADDING_CHECK_NEEDED): New constant.
Try to check that TIME_T_MIN and TIME_T_MAX are actually the min and
max time_t values.
---
private.h | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/private.h b/private.h
index 1d6ddf7..7ddf4e5 100644
--- a/private.h
+++ b/private.h
@@ -43,6 +43,10 @@
# include <stdbool.h>
#endif
+#if __STDC_VERSION__ < 202311
+# define static_assert(cond) extern int static_assert_check[(cond) ? 1 : -1]
+#endif
+
/*
** zdump has been made independent of the rest of the time
** conversion package to increase confidence in the verification it provides.
@@ -833,10 +837,23 @@ ATTRIBUTE_REPRODUCIBLE time_t time2posix_z(timezone_t, time_t);
int: INT_MAX, long: LONG_MAX, long long: LLONG_MAX, \
default: TIME_T_MAX_NO_PADDING) \
: (time_t) -1)
+enum { SIGNED_PADDING_CHECK_NEEDED
+ = _Generic((time_t) 0,
+ signed char: false, short: false,
+ int: false, long: false, long long: false,
+ default: true) };
#else
# define TIME_T_MIN TIME_T_MIN_NO_PADDING
# define TIME_T_MAX TIME_T_MAX_NO_PADDING
-#endif
+enum { SIGNED_PADDING_CHECK_NEEDED = true };
+#endif
+/* Try to check the padding assumptions. Although TIME_T_MAX and the
+ following check can both have undefined behavior on oddball
+ platforms due to shifts exceeding widths of signed integers, these
+ platforms' compilers are likely to diagnose these issues in integer
+ constant expressions, so it shouldn't hurt to check statically. */
+static_assert(! TYPE_SIGNED(time_t) || ! SIGNED_PADDING_CHECK_NEEDED
+ || TIME_T_MAX >> (TYPE_BIT(time_t) - 2) == 1);
/*
** 302 / 1000 is log10(2.0) rounded up.
--
2.38.1
More information about the tz
mailing list