]> Savannah Git Hosting - gnulib.git/commitdiff
intprops: fix INT_MULTIPLY_WRAPV bit-field bug
authorPaul Eggert <eggert@cs.ucla.edu>
Sun, 23 Aug 2020 20:14:13 +0000 (13:14 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Sun, 23 Aug 2020 20:15:35 +0000 (13:15 -0700)
The bug occurs when using INT_MULTIPLY_WRAPV (a, b, c) where B
is a bit-field, on older GCC or non-GCC compilers where we do
things ourselves instead of using __builtin_mul_overflow.
Without this fix, INT_MULTIPLY_WRAPV would not compile, due
to applying sizeof to a bit-field.
* lib/intprops.h (_GL_INT_MULTIPLY_RANGE_OVERFLOW):
Promote B before giving it to TYPE_WIDTH, in case B is a bit-field.

ChangeLog
lib/intprops.h

index 8ab706ac4d7db812817fab6790af1ff09e99f7bf..a6caef9b04935fbbcc76d0aa073857ee0dc704bc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2020-08-23  Paul Eggert  <eggert@cs.ucla.edu>
+
+       intprops: fix INT_MULTIPLY_WRAPV bit-field bug
+       The bug occurs when using INT_MULTIPLY_WRAPV (a, b, c) where B
+       is a bit-field, on older GCC or non-GCC compilers where we do
+       things ourselves instead of using __builtin_mul_overflow.
+       Without this fix, INT_MULTIPLY_WRAPV would not compile, due
+       to applying sizeof to a bit-field.
+       * lib/intprops.h (_GL_INT_MULTIPLY_RANGE_OVERFLOW):
+       Promote B before giving it to TYPE_WIDTH, in case B is a bit-field.
+
 2020-08-23  Bruno Haible  <bruno@clisp.org>
 
        supersede: Avoid a failure when writing to /dev/null in Solaris zones.
index 6ee63244abbd42bdd5c34a06f6c7c82d28a573a0..1bd93d11f953b65d8701ddf996bddb80407965db 100644 (file)
@@ -48,7 +48,7 @@
 /* Minimum and maximum values for integer types and expressions.  */
 
 /* The width in bits of the integer type or expression T.
-   Do not evaluate T.
+   Do not evaluate T.  T must not be a bit-field expression.
    Padding bits are not supported; this is checked at compile-time below.  */
 #define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT)
 
@@ -95,8 +95,9 @@
 #endif
 
 /* Return 1 if the integer type or expression T might be signed.  Return 0
-   if it is definitely unsigned.  This macro does not evaluate its argument,
-   and expands to an integer constant expression.  */
+   if it is definitely unsigned.  T must not be a bit-field expression.
+   This macro does not evaluate its argument, and expands to an
+   integer constant expression.  */
 #if _GL_HAVE___TYPEOF__
 # define _GL_SIGNED_TYPE_OR_EXPR(t) TYPE_SIGNED (__typeof__ (t))
 #else
 #define INT_BITS_STRLEN_BOUND(b) (((b) * 146 + 484) / 485)
 
 /* Bound on length of the string representing an integer type or expression T.
+   T must not be a bit-field expression.
+
    Subtract 1 for the sign bit if T is signed, and then add 1 more for
    a minus sign if needed.
 
    + _GL_SIGNED_TYPE_OR_EXPR (t))
 
 /* Bound on buffer size needed to represent an integer type or expression T,
-   including the terminating null.  */
+   including the terminating null.  T must not be a bit-field expression.  */
 #define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1)
 
 
       ? (EXPR_SIGNED (_GL_INT_CONVERT (tmax, b)) \
          ? (a) < (tmax) / (b) \
          : ((INT_NEGATE_OVERFLOW (b) \
-             ? _GL_INT_CONVERT (b, tmax) >> (TYPE_WIDTH (b) - 1) \
+             ? _GL_INT_CONVERT (b, tmax) >> (TYPE_WIDTH (+ (b)) - 1) \
              : (tmax) / -(b)) \
             <= -1 - (a))) \
       : INT_NEGATE_OVERFLOW (_GL_INT_CONVERT (b, tmin)) && (b) == -1 \