changeset 25838:26c41d8bf170 stable

fix min-val saturation for 64-bit integer addition (bug #54572) * oct-inttypes.h (octave_int_arith_base<T,true>::__signbit): Simplify. (octave_int_arith_base<T,true>::add): In overflow case, set negative limit directly instead of adding signbit to max value.
author John W. Eaton <jwe@octave.org>
date Wed, 29 Aug 2018 14:03:45 -0400
parents 07cb3e098c0a
children 7094f73d4ece
files liboctave/util/oct-inttypes.h
diffstat 1 files changed, 16 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/util/oct-inttypes.h	Wed Aug 29 09:52:08 2018 -0700
+++ b/liboctave/util/oct-inttypes.h	Wed Aug 29 14:03:45 2018 -0400
@@ -544,11 +544,7 @@
   static T
   __signbit (T x)
   {
-#if defined (OCTAVE_HAVE_FAST_INT_OPS)
-    return static_cast<UT> (x) >> std::numeric_limits<T>::digits;
-#else
     return (x < 0) ? 1 : 0;
-#endif
   }
 
   static T
@@ -627,40 +623,42 @@
   add (T x, T y)
   {
 #if defined (OCTAVE_HAVE_FAST_INT_OPS)
+
     // The typecasts do nothing, but they are here to prevent an optimizing
     // compiler from interfering.  Also, the signed operations on small types
     // actually return int.
     T u = static_cast<UT> (x) + static_cast<UT> (y);
     T ux = u ^ x;
     T uy = u ^ y;
-    if ((ux & uy) < 0)
-      {
-        u = octave_int_base<T>::max_val () + __signbit (~u);
-      }
-    return u;
+
+    return ((ux & uy) < 0
+            ? (u < 0
+               ? octave_int_base<T>::max_val ()
+               : octave_int_base<T>::min_val ())
+            : u);
+
 #else
+
     // We shall carefully avoid anything that may overflow.
     T u;
+
     if (y < 0)
       {
         if (x < octave_int_base<T>::min_val () - y)
-          {
-            u = octave_int_base<T>::min_val ();
-          }
+          u = octave_int_base<T>::min_val ();
         else
           u = x + y;
       }
     else
       {
         if (x > octave_int_base<T>::max_val () - y)
-          {
-            u = octave_int_base<T>::max_val ();
-          }
+          u = octave_int_base<T>::max_val ();
         else
           u = x + y;
       }
 
     return u;
+
 #endif
   }
 
@@ -677,7 +675,9 @@
     T uy = u ^ ~y;
     if ((ux & uy) < 0)
       {
-        u = octave_int_base<T>::max_val () + __signbit (~u);
+        u = (__signbit (~u)
+             ? octave_int_base<T>::min_val ()
+             : octave_int_base<T>::max_val ());
       }
     return u;
 #else