On 04/13/2016 07:30 AM, Eric Blake wrote:
wouldn't it be nicer to
force a compiler error in the (unlikely) case that TYPE_TWOS_COMPLEMENT
doesn't hold?

Thanks, good suggestion. I installed the attached patch. It's part 1 of a pair; I'll follow up with a patch to mktime.c that uses intprops.h etc. instead of attempting to do overflow checking by hand.
From ed2c08f3d48e9a94784cbc649f1817bc790387fe Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Wed, 13 Apr 2016 10:49:08 -0700
Subject: [PATCH 1/2] intprops: check two's complement assumption

Suggested by Eric Blake in:
http://lists.gnu.org/archive/html/bug-gnulib/2016-04/msg00016.html
* lib/intprops.h: Include <verify.h>.  Verify that signed char,
short, int, long, and (if available) long long are two's complement.
* modules/intprops (Depends-on): Add 'verify'.
---
 ChangeLog        |  7 +++++++
 lib/intprops.h   | 25 ++++++++++++++++++++-----
 modules/intprops |  1 +
 3 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index a21cf78..e442e7e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2016-04-13  Paul Eggert  <eggert@cs.ucla.edu>
 
+	intprops: check two's complement assumption
+	Suggested by Eric Blake in:
+	http://lists.gnu.org/archive/html/bug-gnulib/2016-04/msg00016.html
+	* lib/intprops.h: Include <verify.h>.  Verify that signed char,
+	short, int, long, and (if available) long long are two's complement.
+	* modules/intprops (Depends-on): Add 'verify'.
+
 	intprops, mktime, strtol: assume two's complement
 	These macros were not portable to every conforming C11 ones'
 	complement platform.  It's not worth the hassle of porting to some
diff --git a/lib/intprops.h b/lib/intprops.h
index de6c324..0be799d 100644
--- a/lib/intprops.h
+++ b/lib/intprops.h
@@ -21,6 +21,7 @@
 #define _GL_INTPROPS_H
 
 #include <limits.h>
+#include <verify.h>
 
 /* Return a value with the common real type of E and V and the value of V.  */
 #define _GL_INT_CONVERT(e, v) (0 * (e) + (v))
@@ -44,10 +45,7 @@
 #define EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0)
 
 
-/* Minimum and maximum values for integer types and expressions.
-   These macros have undefined behavior for signed types that either
-   have padding bits or do not use two's complement.  If this is a
-   problem for you, please let us know how to fix it for your host.  */
+/* Minimum and maximum values for integer types and expressions.  */
 
 /* The maximum and minimum values for the integer type T.  */
 #define TYPE_MINIMUM(t) ((t) ~ TYPE_MAXIMUM (t))
@@ -69,8 +67,25 @@
 #define _GL_SIGNED_INT_MAXIMUM(e)                                       \
   (((_GL_INT_CONVERT (e, 1) << (sizeof ((e) + 0) * CHAR_BIT - 2)) - 1) * 2 + 1)
 
+/* This include file assumes that signed types are two's complement without
+   padding bits; the above macros have undefined behavior otherwise.
+   If this is a problem for you, please let us know how to fix it for your host.
+   As a sanity check, test the assumption for some signed types that
+   <limits.h> bounds.  */
+verify (TYPE_MINIMUM (signed char) == SCHAR_MIN);
+verify (TYPE_MAXIMUM (signed char) == SCHAR_MAX);
+verify (TYPE_MINIMUM (short int) == SHRT_MIN);
+verify (TYPE_MAXIMUM (short int) == SHRT_MAX);
+verify (TYPE_MINIMUM (int) == INT_MIN);
+verify (TYPE_MAXIMUM (int) == INT_MAX);
+verify (TYPE_MINIMUM (long int) == LONG_MIN);
+verify (TYPE_MAXIMUM (long int) == LONG_MAX);
+#ifdef LLONG_MAX
+verify (TYPE_MINIMUM (long long int) == LLONG_MIN);
+verify (TYPE_MAXIMUM (long long int) == LLONG_MAX);
+#endif
 
-/* Return 1 if the __typeof__ keyword works.  This could be done by
+/* Does the __typeof__ keyword work?  This could be done by
    'configure', but for now it's easier to do it by hand.  */
 #if (2 <= __GNUC__ || defined __IBM__TYPEOF__ \
      || (0x5110 <= __SUNPRO_C && !__STDC__))
diff --git a/modules/intprops b/modules/intprops
index 0680adf..ec107ca 100644
--- a/modules/intprops
+++ b/modules/intprops
@@ -5,6 +5,7 @@ Files:
 lib/intprops.h
 
 Depends-on:
+verify
 
 configure.ac:
 
-- 
2.5.5

Reply via email to