>From 931d22eb17dca7efc9c355176fe3303d3ab33bb9 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 14 Apr 2017 18:55:42 -0700 Subject: [PATCH 2/2] intprops: try to avoid tickling similar bugs * lib/intprops.h (_GL_INT_OP_CALC): Document that UT no longer needs to be the same width as T; it can be wider. Change callers so that UT is at least as wide as unsigned int, as I suspect that this is less likely to run into compiler bugs. --- ChangeLog | 6 ++++++ lib/intprops.h | 19 +++++++++---------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 97d1e59..5ed1517 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2017-04-14 Paul Eggert + intprops: try to avoid tickling similar bugs + * lib/intprops.h (_GL_INT_OP_CALC): Document that UT no longer + needs to be the same width as T; it can be wider. + Change callers so that UT is at least as wide as unsigned int, + as I suspect that this is less likely to run into compiler bugs. + intprops: port to Oracle Studio 12.3 x86 Problem reported by Gavin Smith in: http://lists.gnu.org/archive/html/bug-gnulib/2017-04/msg00049.html diff --git a/lib/intprops.h b/lib/intprops.h index 220b509..ca8740d 100644 --- a/lib/intprops.h +++ b/lib/intprops.h @@ -389,10 +389,10 @@ verify (TYPE_WIDTH (unsigned int) == UINT_WIDTH); (_Generic \ (*(r), \ signed char: \ - _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned char, \ + _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ signed char, SCHAR_MIN, SCHAR_MAX), \ short int: \ - _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned short int, \ + _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ short int, SHRT_MIN, SHRT_MAX), \ int: \ _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ @@ -406,10 +406,10 @@ verify (TYPE_WIDTH (unsigned int) == UINT_WIDTH); #else # define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) \ (sizeof *(r) == sizeof (signed char) \ - ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned char, \ + ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ signed char, SCHAR_MIN, SCHAR_MAX) \ : sizeof *(r) == sizeof (short int) \ - ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned short int, \ + ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ short int, SHRT_MIN, SHRT_MAX) \ : sizeof *(r) == sizeof (int) \ ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ @@ -431,9 +431,8 @@ verify (TYPE_WIDTH (unsigned int) == UINT_WIDTH); /* Store the low-order bits of A B into *R, where the operation is given by OP. Use the unsigned type UT for calculation to avoid - overflow problems. *R's type is T, with extremal values TMIN and - TMAX. T must be a signed integer type. Return 1 if the result - overflows. */ + overflow problems. *R's type is T, with extrema TMIN and TMAX. + T must be a signed integer type. Return 1 if the result overflows. */ #define _GL_INT_OP_CALC(a, b, r, op, overflow, ut, t, tmin, tmax) \ (sizeof ((a) op (b)) < sizeof (t) \ ? _GL_INT_OP_CALC1 ((t) (a), (t) (b), r, op, overflow, ut, t, tmin, tmax) \ @@ -449,9 +448,9 @@ verify (TYPE_WIDTH (unsigned int) == UINT_WIDTH); low-order bits of the mathematically-correct answer. Use the unsigned type UT for calculation to avoid undefined behavior on signed integer overflow. Assume that conversion to the result type - T yields the low-order bits in the usual way. UT and T are the - same width, T is two's complement, and there is no padding or trap - representations. + T yields the low-order bits in the usual way. UT is at least as + wide as T and is no narrower than unsigned int, T is two's + complement, and there is no padding or trap representations. According to the C standard, converting UT to T yields an implementation-defined result or signal for values outside T's range. -- 2.9.3