From: Paul Eggert <eggert@cs.ucla.edu>
Date: Thu, 19 May 2011 08:36:25 +0000 (-0700)
Subject: intprops: work around C compiler bugs
X-Git-Tag: v0.1~2766
X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=8cc0fee;p=gnulib.git

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>.
---

diff --git a/ChangeLog b/ChangeLog
index 86001d5f81..d12db037ce 100644
--- 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
diff --git a/lib/intprops.h b/lib/intprops.h
index a84bd6af53..9107a4bbea 100644
--- 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.  */