changeset 14760:fd6c5b527040

intprops: work around C compiler bugs * lib/intprops.h (INT_MULTIPLY_RANGE_OVERFLOW): Work around compiler bug in Sun C 5.11 2010/08/13 and other compilers; see <http://lists.gnu.org/archive/html/bug-gnulib/2011-05/msg00401.html>.
author Paul Eggert <eggert@cs.ucla.edu>
date Thu, 19 May 2011 01:36:25 -0700
parents 0f9cae3e684f
children 6c5502aeb486
files ChangeLog lib/intprops.h
diffstat 2 files changed, 16 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2011-05-19  Paul Eggert  <eggert@cs.ucla.edu>
 
+	intprops: work around C compiler bugs
+	* lib/intprops.h (INT_MULTIPLY_RANGE_OVERFLOW): Work around compiler
+	bug in Sun C 5.11 2010/08/13 and other compilers; see
+	<http://lists.gnu.org/archive/html/bug-gnulib/2011-05/msg00401.html>.
+
 	intprops: TYPE_IS_INTEGER, TYPE_SIGNED not integer constant exprs
 	* doc/intprops.texi (Integer Type Determination): Fix
 	documentation for TYPE_IS_INTEGER: it returns an constant
--- a/lib/intprops.h
+++ b/lib/intprops.h
@@ -179,16 +179,21 @@
    : 0 < (a))
 
 /* Return 1 if A * B would overflow in [MIN,MAX] arithmetic.
-   See above for restrictions.  */
+   See above for restrictions.  Avoid && and || as they tickle
+   bugs in Sun C 5.11 2010/08/13 and other compilers; see
+   <http://lists.gnu.org/archive/html/bug-gnulib/2011-05/msg00401.html>.  */
 #define INT_MULTIPLY_RANGE_OVERFLOW(a, b, min, max)     \
   ((b) < 0                                              \
    ? ((a) < 0                                           \
       ? (a) < (max) / (b)                               \
-      : (b) < -1 && (min) / (b) < (a))                  \
-   : (0 < (b)                                           \
-      && ((a) < 0                                       \
-          ? (a) < (min) / (b)                           \
-          : (max) / (b) < (a))))
+      : (b) == -1                                       \
+      ? 0                                               \
+      : (min) / (b) < (a))                              \
+   : (b) == 0                                           \
+   ? 0                                                  \
+   : ((a) < 0                                           \
+      ? (a) < (min) / (b)                               \
+      : (max) / (b) < (a)))
 
 /* Return 1 if A / B would overflow in [MIN,MAX] arithmetic.
    See above for restrictions.  Do not check for division by zero.  */