[tz] [PROPOSED 2/2] Port GCC_DEBUG_OPTIONS to GCC 7; avoid recursion

Paul Eggert eggert at cs.ucla.edu
Thu May 18 23:15:58 UTC 2017


* Makefile (GCC_INSTRUMENT): New option.
(GCC_DEBUG_FLAGS): Update for GCC 7.
* date.c (usage): Now _Noreturn.
* difftime.c (difftime): Omit const attribute, as this is
now in the declaration.
* localtime.c (transtime): Omit ATTRIBUTE_PURE, as GCC is now
smart enough to deduce it.
(time2posix_z, posix2time_z): Omit ATTRIBUTE_PURE, as it is
problematic whether these functions are actually pure.
* localtime.c (leaps_thru_end_of_nonneg):
* zdump.c (delta_nonneg):
New function, with the nonnegative part of the old.
* localtime.c (leaps_thru_end_of):
* zdump.c (delta): Use new function to avoid recursion; this
pacifies GCC 7 without needing an attribute.
* private.h (difftime): Declare with ATTRIBUTE_CONST.
---
 Makefile    | 35 +++++++++++++++++++++--------------
 date.c      |  2 +-
 difftime.c  |  2 +-
 localtime.c | 19 +++++++++++++------
 private.h   |  2 +-
 zdump.c     | 14 ++++++++++----
 6 files changed, 47 insertions(+), 27 deletions(-)

diff --git a/Makefile b/Makefile
index bcfdcb2..c62d46f 100644
--- a/Makefile
+++ b/Makefile
@@ -159,20 +159,27 @@ LDLIBS=
 #	(or some other number) to set the maximum time zone abbreviation length
 #	that zic will accept without a warning (the default is 6)
 #  $(GCC_DEBUG_FLAGS) if you are using recent GCC and want lots of checking
-GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common -fstrict-aliasing \
-	-Wall -Wextra \
-	-Wbad-function-cast -Wcast-align -Wdate-time \
-	-Wdeclaration-after-statement \
-	-Wdouble-promotion \
-	-Wformat=2 -Winit-self -Wjump-misses-init \
-	-Wlogical-op -Wmissing-prototypes -Wnested-externs \
-	-Wold-style-definition -Woverlength-strings -Wpointer-arith \
-	-Wshadow -Wstrict-prototypes -Wsuggest-attribute=const \
-	-Wsuggest-attribute=format -Wsuggest-attribute=noreturn \
-	-Wsuggest-attribute=pure -Wtrampolines \
-	-Wundef -Wunused -Wwrite-strings \
-	-Wno-address -Wno-format-nonliteral -Wno-sign-compare \
-	-Wno-type-limits -Wno-unused-parameter
+# Select instrumentation via "make GCC_INSTRUMENT='whatever'".
+GCC_INSTRUMENT = \
+  -fsanitize=undefined -fsanitize-address-use-after-scope \
+  -fsanitize-undefined-trap-on-error -fstack-protector
+GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \
+  $(GCC_INSTRUMENT) \
+  -Wall -Wextra \
+  -Walloc-size-larger-than=100000 -Warray-bounds=2 \
+  -Wbad-function-cast -Wcast-align -Wdate-time \
+  -Wdeclaration-after-statement -Wdouble-promotion \
+  -Wformat=2 -Wformat-overflow=2 -Wformat-signedness -Wformat-truncation \
+  -Winit-self -Wjump-misses-init -Wlogical-op \
+  -Wmissing-declarations -Wmissing-prototypes -Wnested-externs \
+  -Wold-style-definition -Woverlength-strings -Wpointer-arith \
+  -Wshadow -Wshift-overflow=2 -Wstrict-prototypes -Wstringop-overflow=5 \
+  -Wsuggest-attribute=const -Wsuggest-attribute=format \
+  -Wsuggest-attribute=noreturn -Wsuggest-attribute=pure \
+  -Wtrampolines -Wundef -Wuninitialized -Wunused \
+  -Wvariadic-macros -Wvla -Wwrite-strings \
+  -Wno-address -Wno-format-nonliteral -Wno-sign-compare \
+  -Wno-type-limits -Wno-unused-parameter
 #
 # If you want to use System V compatibility code, add
 #	-DUSG_COMPAT
diff --git a/date.c b/date.c
index 98b907f..269825d 100644
--- a/date.c
+++ b/date.c
@@ -54,7 +54,7 @@ static void		display(const char *, time_t);
 static void		dogmt(void);
 static void		errensure(void);
 static void		timeout(FILE *, const char *, const struct tm *);
-static void		usage(void);
+static _Noreturn void	usage(void);
 
 int
 main(const int argc, char *argv[])
diff --git a/difftime.c b/difftime.c
index ba2fd03..856234a 100644
--- a/difftime.c
+++ b/difftime.c
@@ -14,7 +14,7 @@ dminus(double x)
   return -x;
 }
 
-double ATTRIBUTE_CONST
+double
 difftime(time_t time1, time_t time0)
 {
 	/*
diff --git a/localtime.c b/localtime.c
index 0ccd8ba..a951cab 100644
--- a/localtime.c
+++ b/localtime.c
@@ -919,7 +919,7 @@ getrule(const char *strp, register struct rule *const rulep)
 ** effect, calculate the year-relative time that rule takes effect.
 */
 
-static int_fast32_t ATTRIBUTE_PURE
+static int_fast32_t
 transtime(const int year, register const struct rule *const rulep,
 	  const int_fast32_t offset)
 {
@@ -1588,11 +1588,18 @@ offtime(const time_t *timep, long offset)
 ** where, to make the math easy, the answer for year zero is defined as zero.
 */
 
-static int ATTRIBUTE_PURE
+static int
+leaps_thru_end_of_nonneg(int y)
+{
+  return y / 4 - y / 100 + y / 400;
+}
+
+static int
 leaps_thru_end_of(register const int y)
 {
-	return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
-		-(leaps_thru_end_of(-(y + 1)) + 1);
+  return (y < 0
+	  ? -1 - leaps_thru_end_of_nonneg(-1 - y)
+	  : leaps_thru_end_of_nonneg(y));
 }
 
 static struct tm *
@@ -2210,7 +2217,7 @@ leapcorr(struct state const *sp, time_t t)
 	return 0;
 }
 
-NETBSD_INSPIRED_EXTERN time_t ATTRIBUTE_PURE
+NETBSD_INSPIRED_EXTERN time_t
 time2posix_z(struct state *sp, time_t t)
 {
   return t - leapcorr(sp, t);
@@ -2232,7 +2239,7 @@ time2posix(time_t t)
   return t;
 }
 
-NETBSD_INSPIRED_EXTERN time_t ATTRIBUTE_PURE
+NETBSD_INSPIRED_EXTERN time_t
 posix2time_z(struct state *sp, time_t t)
 {
 	time_t	x;
diff --git a/private.h b/private.h
index 6886185..1e61592 100644
--- a/private.h
+++ b/private.h
@@ -396,7 +396,7 @@ typedef time_tz tz_time_t;
 
 char *ctime(time_t const *);
 char *ctime_r(time_t const *, char *);
-double difftime(time_t, time_t);
+double difftime(time_t, time_t) ATTRIBUTE_CONST;
 struct tm *gmtime(time_t const *);
 struct tm *gmtime_r(time_t const *restrict, struct tm *restrict);
 struct tm *localtime(time_t const *);
diff --git a/zdump.c b/zdump.c
index c19b3b4..7cde3d3 100644
--- a/zdump.c
+++ b/zdump.c
@@ -683,17 +683,15 @@ hunt(timezone_t tz, char *name, time_t lot, time_t hit)
 }
 
 /*
-** Thanks to Paul Eggert for logic used in delta.
+** Thanks to Paul Eggert for logic used in delta_nonneg.
 */
 
 static intmax_t
-delta(struct tm * newp, struct tm *oldp)
+delta_nonneg(struct tm *newp, struct tm *oldp)
 {
 	register intmax_t	result;
 	register int		tmy;
 
-	if (newp->tm_year < oldp->tm_year)
-		return -delta(oldp, newp);
 	result = 0;
 	for (tmy = oldp->tm_year; tmy < newp->tm_year; ++tmy)
 		result += DAYSPERNYEAR + isleap_sum(tmy, TM_YEAR_BASE);
@@ -707,6 +705,14 @@ delta(struct tm * newp, struct tm *oldp)
 	return result;
 }
 
+static intmax_t
+delta(struct tm *newp, struct tm *oldp)
+{
+  return (newp->tm_year < oldp->tm_year
+	  ? -delta_nonneg(oldp, newp)
+	  : delta_nonneg(newp, oldp));
+}
+
 #ifndef TM_GMTOFF
 /* Return A->tm_yday, adjusted to compare it fairly to B->tm_yday.
    Assume A and B differ by at most one year.  */
-- 
2.9.4



More information about the tz mailing list