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

Reply via email to