NetBSD enables -Wcast-qual when building its localtime.c.
* Makefile (GCC_DEBUG_FLAGS): Add -Wcast-qual.
* localtime.c (TYPECVT, UNCONST): New macros.
(tzname) [2 <= HAVE_TZNAME + TZ_TIME_T]:
(update_tzname_etc, settzname, localsub, gmtsub):
Use UNCONST instead of casting to char *.
---
Makefile | 3 ++-
localtime.c | 31 ++++++++++++++++++++++---------
2 files changed, 24 insertions(+), 10 deletions(-)
diff --git a/Makefile b/Makefile
index f1ce7abb..2130582c 100644
--- a/Makefile
+++ b/Makefile
@@ -320,7 +320,8 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 \
$(GCC_INSTRUMENT) \
-Wall -Wextra \
-Walloc-size-larger-than=100000 -Warray-bounds=2 \
- -Wbad-function-cast -Wbidi-chars=any,ucn -Wcast-align=strict -Wdate-time \
+ -Wbad-function-cast -Wbidi-chars=any,ucn -Wcast-align=strict -Wcast-qual \
+ -Wdate-time \
-Wdeclaration-after-statement -Wdouble-promotion \
-Wduplicated-branches -Wduplicated-cond -Wflex-array-member-not-at-end \
-Wformat=2 -Wformat-overflow=2 -Wformat-signedness -Wformat-truncation \
diff --git a/localtime.c b/localtime.c
index 441c5edd..9c185e66 100644
--- a/localtime.c
+++ b/localtime.c
@@ -37,6 +37,22 @@ static int lock(void) { return 0; }
static void unlock(void) { }
#endif
+/* Convert to TYPE the value of the expression EXPR. Use C99+ implicit
+ conversion if available, as it is less powerful and therefore safer. */
+#if PORT_TO_C89
+# define TYPECVT(type, expr) ((type) (expr))
+#else
+# define TYPECVT(type, expr) ((type) {expr})
+#endif
+
+/* Unless intptr_t is missing, pacify gcc -Wcast-qual on char const * exprs.
+ This is a macro so that it can be used in static initializers. */
+#ifdef INTPTR_MAX
+# define UNCONST(a) ((char *) (intptr_t) TYPECVT (char const *, a))
+#else
+# define UNCONST(a) TYPECVT (char const *, a)
+#endif
+
/* A signed type wider than int, so that we can add 1900 + tm_mon/12 to tm_year
without overflow. The static_assert checks that it is indeed wider
than int; if this fails on your platform please let us know. */
@@ -290,10 +306,7 @@ static struct tm tm;
#endif
# if 2 <= HAVE_TZNAME + TZ_TIME_T
-char * tzname[2] = {
- (char *) wildabbr,
- (char *) wildabbr
-};
+char *tzname[2] = { UNCONST(wildabbr), UNCONST(wildabbr) };
# endif
# if 2 <= USG_COMPAT + TZ_TIME_T
long timezone;
@@ -378,7 +391,7 @@ static void
update_tzname_etc(struct state const *sp, struct ttinfo const *ttisp)
{
# if HAVE_TZNAME
- tzname[ttisp->tt_isdst] = (char *) &sp->chars[ttisp->tt_desigidx];
+ tzname[ttisp->tt_isdst] = UNCONST(&sp->chars[ttisp->tt_desigidx]);
# endif
# if USG_COMPAT
if (!ttisp->tt_isdst)
@@ -419,7 +432,7 @@ settzname(void)
int stddst_mask = 0;
# if HAVE_TZNAME
- tzname[0] = tzname[1] = (char *) (sp ? wildabbr : utc);
+ tzname[0] = tzname[1] = UNCONST(sp ? wildabbr : utc);
stddst_mask = 3;
# endif
# if USG_COMPAT
@@ -1657,7 +1670,7 @@ localsub(struct state const *sp, time_t const *timep,
int_fast32_t setname,
if (result) {
result->tm_isdst = ttisp->tt_isdst;
# ifdef TM_ZONE
- result->TM_ZONE = (char *) &sp->chars[ttisp->tt_desigidx];
+ result->TM_ZONE = UNCONST(&sp->chars[ttisp->tt_desigidx]);
# endif
if (setname)
update_tzname_etc(sp, ttisp);
@@ -1725,8 +1738,8 @@ gmtsub(ATTRIBUTE_MAYBE_UNUSED struct state const *sp,
time_t const *timep,
** "+xx" or "-xx" if offset is non-zero,
** but this is no time for a treasure hunt.
*/
- tmp->TM_ZONE = ((char *)
- (offset ? wildabbr : gmtptr ? gmtptr->chars : utc));
+ tmp->TM_ZONE = UNCONST(offset ? wildabbr
+ : gmtptr ? gmtptr->chars : utc);
#endif /* defined TM_ZONE */
return result;
}
--
2.47.1