>From 5d4cdc813c6751a833047ece3dbcf38d976270a6 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 23 Aug 2020 13:14:13 -0700 Subject: [PATCH 1/2] 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. --- ChangeLog | 11 +++++++++++ lib/intprops.h | 13 ++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8ab706ac4..a6caef9b0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2020-08-23 Paul Eggert + + 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 supersede: Avoid a failure when writing to /dev/null in Solaris zones. diff --git a/lib/intprops.h b/lib/intprops.h index 6ee63244a..1bd93d11f 100644 --- a/lib/intprops.h +++ b/lib/intprops.h @@ -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 @@ -109,6 +110,8 @@ #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. @@ -120,7 +123,7 @@ + _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) @@ -566,7 +569,7 @@ ? (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 \ -- 2.17.1