exporting patch:
# HG changeset patch
# User Daniel J Sebald <daniel.sebald@ieee.org>
# Date 1535764572 18000
#      Fri Aug 31 20:16:12 2018 -0500
# Node ID 727e6d8e5f507175f844f926ac0fe1ed4806569f
# Parent  4c25d8d3a0ae16a844bef238bb3effaf4564fa82
Remove the possible use of long double type for integer arithmetic (but #54572)

* mk-octave-config-h.sh: Remove define/undef for OCTAVE_INT_USE_LONG_DOUBLE.

* oct-inttypes.cc: Remove all case statements and code corresponding to
  OCTAVE_INT_USE_LONG_DOUBLE being true.

* oct-inttypes.h: Ditto.  There is one case where the code seems to pertain
  to the conversion between int64_t and double.  That code has been retained
  and the definition OCTAVE_DEFINE_LONG_DOUBLE_INT_CMP_OP change to
  OCTAVE_DEFINE_INT64_DOUBLE_CMP_OP.

* oct-conf-post.in.h: Remove OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OP and
  OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OPS undefinitions.

diff --git a/build-aux/mk-octave-config-h.sh b/build-aux/mk-octave-config-h.sh
--- a/build-aux/mk-octave-config-h.sh
+++ b/build-aux/mk-octave-config-h.sh
@@ -243,7 +243,6 @@ if test -z "$sizeof_long_double"; then
 fi
 
 if test $sizeof_long_double -ge 10 && test $have_roundl = yes; then
-  echo "#  define OCTAVE_INT_USE_LONG_DOUBLE 1"
   if test $sizeof_long_double -lt 16; then
     cat << EOF
 #  if (defined (__i386__) || defined (__x86_64__)) && defined (__GNUC__)
@@ -257,7 +256,6 @@ EOF
   fi
 else
   cat << EOF
-/* #  undef OCTAVE_INT_USE_LONG_DOUBLE */
 /* #  undef OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED */
 EOF
 fi
diff --git a/liboctave/util/oct-inttypes.cc b/liboctave/util/oct-inttypes.cc
--- a/liboctave/util/oct-inttypes.cc
+++ b/liboctave/util/oct-inttypes.cc
@@ -91,133 +91,6 @@ octave_int_base<T>::convert_real (const 
 
 INSTANTIATE_CONVERT_REAL (double);
 INSTANTIATE_CONVERT_REAL (float);
-#if defined (OCTAVE_INT_USE_LONG_DOUBLE)
-INSTANTIATE_CONVERT_REAL (long double);
-#endif
-
-#if defined (OCTAVE_INT_USE_LONG_DOUBLE)
-
-#  if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
-
-#    define DEFINE_OCTAVE_LONG_DOUBLE_CMP_OP_TEMPLATES(T)       \
-  template <typename xop>                                       \
-  bool                                                          \
-  octave_int_cmp_op::external_mop (double x, T y)               \
-  {                                                             \
-    unsigned int oldcw = octave_begin_long_double_rounding ();  \
-                                                                \
-    bool retval = xop::op (static_cast<long double> (x),        \
-                           static_cast<long double> (y));       \
-                                                                \
-    octave_end_long_double_rounding (oldcw);                    \
-                                                                \
-    return retval;                                              \
-  }                                                             \
-                                                                \
-  template <typename xop>                                       \
-  bool                                                          \
-  octave_int_cmp_op::external_mop (T x, double y)               \
-  {                                                             \
-    unsigned int oldcw = octave_begin_long_double_rounding ();  \
-                                                                \
-    bool retval = xop::op (static_cast<long double> (x),        \
-                           static_cast<long double> (y));       \
-                                                                \
-    octave_end_long_double_rounding (oldcw);                    \
-                                                                \
-    return retval;                                              \
-  }
-
-DEFINE_OCTAVE_LONG_DOUBLE_CMP_OP_TEMPLATES (int64_t)
-DEFINE_OCTAVE_LONG_DOUBLE_CMP_OP_TEMPLATES (uint64_t)
-
-#    define INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP(OP, T)           \
-  template OCTAVE_API bool                                              \
-  octave_int_cmp_op::external_mop<octave_int_cmp_op::OP> (double, T);   \
-                                                                        \
-  template OCTAVE_API bool                                              \
-  octave_int_cmp_op::external_mop<octave_int_cmp_op::OP> (T, double)
-
-#    define INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OPS(T)      \
-  INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP (lt, T);           \
-  INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP (le, T);           \
-  INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP (gt, T);           \
-  INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP (ge, T);           \
-  INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP (eq, T);           \
-  INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP (ne, T)
-
-INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OPS (int64_t);
-INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OPS (uint64_t);
-
-uint64_t
-octave_external_uint64_uint64_mul (uint64_t x, uint64_t y)
-{
-  unsigned int oldcw = octave_begin_long_double_rounding ();
-
-  uint64_t retval = octave_int_arith_base<uint64_t, false>::mul_internal (x, y);
-
-  octave_end_long_double_rounding (oldcw);
-
-  return retval;
-}
-
-int64_t
-octave_external_int64_int64_mul (int64_t x, int64_t y)
-{
-  unsigned int oldcw = octave_begin_long_double_rounding ();
-
-  int64_t retval = octave_int_arith_base<int64_t, true>::mul_internal (x, y);
-
-  octave_end_long_double_rounding (oldcw);
-
-  return retval;
-}
-
-// Note that if we return long double it is apparently possible for
-// truncation to happen at the point of storing the result in retval,
-// which can happen after we end long double rounding.  Attempt to avoid
-// that problem by storing the full precision temporary value in the
-// integer value before we end the long double rounding mode.
-// Similarly, the conversion from the 64-bit integer type to long double
-// must also occur in long double rounding mode.
-
-#    define OCTAVE_LONG_DOUBLE_OP(T, OP, NAME)                  \
-  T                                                             \
-  external_double_ ## T ## _ ## NAME (double x, T y)            \
-  {                                                             \
-    unsigned int oldcw = octave_begin_long_double_rounding ();  \
-                                                                \
-    T retval = T (x OP static_cast<long double> (y.value ()));  \
-                                                                \
-    octave_end_long_double_rounding (oldcw);                    \
-                                                                \
-    return retval;                                              \
-  }                                                             \
-                                                                \
-  T                                                             \
-  external_ ## T ## _double_ ## NAME (T x, double y)            \
-  {                                                             \
-    unsigned int oldcw = octave_begin_long_double_rounding ();  \
-                                                                \
-    T retval = T (static_cast<long double> (x.value ()) OP y);  \
-                                                                \
-    octave_end_long_double_rounding (oldcw);                    \
-                                                                \
-    return retval;                                              \
-  }
-
-#    define OCTAVE_LONG_DOUBLE_OPS(T)           \
-  OCTAVE_LONG_DOUBLE_OP (T, +, add);            \
-  OCTAVE_LONG_DOUBLE_OP (T, -, sub);            \
-  OCTAVE_LONG_DOUBLE_OP (T, *, mul);            \
-  OCTAVE_LONG_DOUBLE_OP (T, /, div)
-
-OCTAVE_LONG_DOUBLE_OPS(octave_int64);
-OCTAVE_LONG_DOUBLE_OPS(octave_uint64);
-
-#  endif
-
-#else
 
 // Define comparison operators
 
@@ -696,8 +569,6 @@ INSTANTIATE_INT64_DOUBLE_CMP_OP(ge);
 INSTANTIATE_INT64_DOUBLE_CMP_OP(eq);
 INSTANTIATE_INT64_DOUBLE_CMP_OP(ne);
 
-#endif
-
 template <typename T>
 octave_int<T>
 pow (const octave_int<T>& a, const octave_int<T>& b)
diff --git a/liboctave/util/oct-inttypes.h b/liboctave/util/oct-inttypes.h
--- a/liboctave/util/oct-inttypes.h
+++ b/liboctave/util/oct-inttypes.h
@@ -47,26 +47,6 @@ typedef octave_int<uint16_t> octave_uint
 typedef octave_int<uint32_t> octave_uint32;
 typedef octave_int<uint64_t> octave_uint64;
 
-#if defined (OCTAVE_INT_USE_LONG_DOUBLE)
-
-namespace octave
-{
-  namespace math
-  {
-    inline long double round (long double x)
-    {
-      return std::roundl (x);
-    }
-
-    inline long double isnan (long double x)
-    {
-      return isnan (static_cast<double> (x));
-    }
-  }
-}
-
-#endif
-
 // FIXME: we define this by our own because some compilers, such as
 // MSVC, do not provide std::abs (int64_t) and std::abs (uint64_t).  In
 // the future, it should go away in favor of std::abs.
@@ -258,68 +238,11 @@ public:
     return xop::op (x, static_cast<double> (y));
   }
 
-#if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
-
-#  define OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_CMP_OPS(T)    \
-  template <typename xop>                                       \
-  static OCTAVE_API bool external_mop (double, T);              \
-                                                                \
-  template <typename xop>                                       \
-  static OCTAVE_API bool external_mop (T, double)
-
-  OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_CMP_OPS (int64_t);
-  OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_CMP_OPS (uint64_t);
-
-#endif
-
-  // Typecasting to doubles won't work properly for 64-bit integers --
-  // they lose precision.  If we have long doubles, use them...
-
-#if defined (OCTAVE_INT_USE_LONG_DOUBLE)
-
-#  if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
-
-#    define OCTAVE_DEFINE_LONG_DOUBLE_INT_CMP_OP(T)     \
-  template <typename xop>                               \
-  static bool mop (double x, T y)                       \
-  {                                                     \
-    return external_mop<xop> (x, y);                    \
-  }                                                     \
-                                                        \
-  template <typename xop>                               \
-  static bool mop (T x, double y)                       \
-  {                                                     \
-    return external_mop<xop> (x, y);                    \
-  }
-
-#  else
-
-#    define OCTAVE_DEFINE_LONG_DOUBLE_INT_CMP_OP(T)     \
-  template <typename xop>                               \
-  static bool mop (double x, T y)                       \
-  {                                                     \
-    return xop::op (static_cast<long double> (x),       \
-                    static_cast<long double> (y));      \
-  }                                                     \
-                                                        \
-  template <typename xop>                               \
-  static bool mop (T x, double y)                       \
-  {                                                     \
-    return xop::op (static_cast<long double> (x),       \
-                    static_cast<long double> (y));      \
-  }
-
-#  endif
-
-#else
-
-  // ... otherwise, use external handlers
-
   // FIXME: We could declare directly the mop methods as external, but
   // we can't do this because bugs in gcc (<= 4.3) prevent explicit
   // instantiations later in that case.
 
-#  define OCTAVE_DEFINE_LONG_DOUBLE_INT_CMP_OP(T)       \
+#  define OCTAVE_DEFINE_INT64_DOUBLE_CMP_OP(T)          \
   template <typename xop>                               \
   static OCTAVE_API bool emulate_mop (double, T);       \
                                                         \
@@ -338,10 +261,8 @@ public:
     return emulate_mop<xop> (x, y);                     \
   }
 
-#endif
-
-  OCTAVE_DEFINE_LONG_DOUBLE_INT_CMP_OP (int64_t)
-  OCTAVE_DEFINE_LONG_DOUBLE_INT_CMP_OP (uint64_t)
+  OCTAVE_DEFINE_INT64_DOUBLE_CMP_OP (int64_t)
+  OCTAVE_DEFINE_INT64_DOUBLE_CMP_OP (uint64_t)
 
 #undef OCTAVE_DEFINE_LONG_DOUBLE_INT_CMP_OP
 };
@@ -524,54 +445,12 @@ public:
   static T mod (T x, T y) { return y != 0 ? x % y : x; }
 };
 
-#if defined (OCTAVE_INT_USE_LONG_DOUBLE)
-
-// Handle 64-bit multiply using long double.
-
-#  if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
-
-extern OCTAVE_API uint64_t
-octave_external_uint64_uint64_mul (uint64_t, uint64_t);
-
-#  endif
-
-template <>
-inline uint64_t
-octave_int_arith_base<uint64_t, false>::mul_internal (uint64_t x, uint64_t y)
-{
-  uint64_t retval;
-
-  long double p = static_cast<long double> (x) * static_cast<long double> (y);
-
-  if (p > static_cast<long double> (octave_int_base<uint64_t>::max_val ()))
-    retval = octave_int_base<uint64_t>::max_val ();
-  else
-    retval = static_cast<uint64_t> (p);
-
-  return retval;
-}
-
-template <>
-inline uint64_t
-octave_int_arith_base<uint64_t, false>::mul (uint64_t x, uint64_t y)
-{
-#  if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
-  return octave_external_uint64_uint64_mul (x, y);
-#  else
-  return mul_internal (x, y);
-#  endif
-}
-
-#else
-
 // Special handler for 64-bit integer multiply.
 
 template <>
 OCTAVE_API uint64_t
 octave_int_arith_base<uint64_t, false>::mul_internal (uint64_t, uint64_t);
 
-#endif
-
 template <typename T>
 class octave_int_arith_base<T, true> : octave_int_base<T>
 {
@@ -730,56 +609,12 @@ public:
   }
 };
 
-#if defined (OCTAVE_INT_USE_LONG_DOUBLE)
-
-// Handle 64-bit multiply using long double
-
-#  if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
-
-extern OCTAVE_API int64_t
-octave_external_int64_int64_mul (int64_t, int64_t);
-
-#  endif
-
-template <>
-inline int64_t
-octave_int_arith_base<int64_t, true>::mul_internal (int64_t x, int64_t y)
-{
-  int64_t retval;
-
-  long double p = static_cast<long double> (x) * static_cast<long double> (y);
-
-  if (p > static_cast<long double> (octave_int_base<int64_t>::max_val ()))
-    retval = octave_int_base<int64_t>::max_val ();
-  else if (p < static_cast<long double> (octave_int_base<int64_t>::min_val ()))
-    retval = octave_int_base<int64_t>::min_val ();
-  else
-    retval = static_cast<int64_t> (p);
-
-  return retval;
-}
-
-template <>
-inline int64_t
-octave_int_arith_base<int64_t, true>::mul (int64_t x, int64_t y)
-{
-#  if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
-  return octave_external_int64_int64_mul (x, y);
-#  else
-  return mul_internal (x, y);
-#  endif
-}
-
-#else
-
 // Special handler for 64-bit integer multiply.
 
 template <>
 OCTAVE_API int64_t
 octave_int_arith_base<int64_t, true>::mul_internal (int64_t, int64_t);
 
-#endif
-
 // This class simply selects the proper arithmetics.
 template <typename T>
 class octave_int_arith
@@ -813,13 +648,6 @@ public:
   octave_int (float d)
     : ival (octave_int_base<T>::convert_real (d)) { }
 
-#if defined (OCTAVE_INT_USE_LONG_DOUBLE)
-
-  octave_int (long double d)
-    : ival (octave_int_base<T>::convert_real (d)) { }
-
-#endif
-
   octave_int (bool b) : ival (b) { }
 
   template <typename U>
@@ -1095,26 +923,6 @@ bitshift (const octave_int<T>& a, int n,
     return a & mask;
 }
 
-#if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
-
-#  define OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OP(T, OP)     \
-  extern OCTAVE_API T                                           \
-  external_double_ ## T ## _ ## OP (double x, T y);             \
-                                                                \
-  extern OCTAVE_API T                                           \
-  external_ ## T ## _double_ ## OP (T x, double y)
-
-#  define OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OPS(T)        \
-  OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OP (T, add);          \
-  OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OP (T, sub);          \
-  OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OP (T, mul);          \
-  OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OP (T, div)
-
-  OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OPS (octave_int64);
-  OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OPS (octave_uint64);
-
-#endif
-
 #define OCTAVE_INT_DOUBLE_BIN_OP0(OP)                           \
   template <typename T>                                         \
   inline octave_int<T>                                          \
@@ -1130,80 +938,6 @@ bitshift (const octave_int<T>& a, int n,
     return octave_int<T> (x OP static_cast<double> (y));        \
   }
 
-#if defined (OCTAVE_INT_USE_LONG_DOUBLE)
-
-// Handle mixed op using long double.
-
-#  if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
-
-#    define OCTAVE_INT_DOUBLE_BIN_OP(OP, NAME)                  \
-  OCTAVE_INT_DOUBLE_BIN_OP0(OP)                                 \
-                                                                \
-  template <>                                                   \
-  inline octave_int64                                           \
-  operator OP (const double& x, const octave_int64& y)          \
-  {                                                             \
-    return external_double_octave_int64_ ## NAME (x, y);        \
-  }                                                             \
-                                                                \
-  template <>                                                   \
-  inline octave_uint64                                          \
-  operator OP (const double& x, const octave_uint64& y)         \
-  {                                                             \
-    return external_double_octave_uint64_ ## NAME (x, y);       \
-  }                                                             \
-                                                                \
-  template <>                                                   \
-  inline octave_int64                                           \
-  operator OP (const octave_int64& x, const double& y)          \
-  {                                                             \
-    return external_octave_int64_double_ ## NAME (x, y);        \
-  }                                                             \
-                                                                \
-  template <>                                                   \
-  inline octave_uint64                                          \
-  operator OP (const octave_uint64& x, const double& y)         \
-  {                                                             \
-    return external_octave_uint64_double_ ## NAME (x, y);       \
-  }
-
-#  else
-
-#    define OCTAVE_INT_DOUBLE_BIN_OP(OP, NAME)                          \
-  OCTAVE_INT_DOUBLE_BIN_OP0(OP)                                         \
-                                                                        \
-  template <>                                                           \
-  inline octave_int64                                                   \
-  operator OP (const double& x, const octave_int64& y)                  \
-  {                                                                     \
-    return octave_int64 (x OP static_cast<long double> (y.value ()));   \
-  }                                                                     \
-                                                                        \
-  template <>                                                           \
-  inline octave_uint64                                                  \
-  operator OP (const double& x, const octave_uint64& y)                 \
-  {                                                                     \
-    return octave_uint64 (x OP static_cast<long double> (y.value ()));  \
-  }                                                                     \
-                                                                        \
-  template <>                                                           \
-  inline octave_int64                                                   \
-  operator OP (const octave_int64& x, const double& y)                  \
-  {                                                                     \
-    return octave_int64 (static_cast<long double> (x.value ()) OP y);   \
-  }                                                                     \
-                                                                        \
-  template <>                                                           \
-  inline octave_uint64                                                  \
-  operator OP (const octave_uint64& x, const double& y)                 \
-  {                                                                     \
-    return octave_uint64 (static_cast<long double> (x.value ()) OP y);  \
-  }
-
-#  endif
-
-#else
-
 // External handlers.
 
 #  define OCTAVE_INT_DOUBLE_BIN_OP(OP, NAME)            \
@@ -1225,8 +959,6 @@ bitshift (const octave_int<T>& a, int n,
   OCTAVE_API octave_uint64                              \
   operator OP (const octave_uint64&, const double&);
 
-#endif
-
 OCTAVE_INT_DOUBLE_BIN_OP (+, add)
 OCTAVE_INT_DOUBLE_BIN_OP (-, sub)
 OCTAVE_INT_DOUBLE_BIN_OP (*, mul)
@@ -1234,8 +966,6 @@ OCTAVE_INT_DOUBLE_BIN_OP (/, div)
 
 #undef OCTAVE_INT_DOUBLE_BIN_OP0
 #undef OCTAVE_INT_DOUBLE_BIN_OP
-#undef OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OP
-#undef OCTAVE_DECLARE_EXTERNAL_LONG_DOUBLE_INT_OPS
 
 #define OCTAVE_INT_DOUBLE_CMP_OP(OP, NAME)                              \
   template <typename T>                                                 \
diff --git a/oct-conf-post.in.h b/oct-conf-post.in.h
--- a/oct-conf-post.in.h
+++ b/oct-conf-post.in.h
@@ -121,17 +121,6 @@ typedef unsigned long ino_t;
 #  define OCTAVE_HAVE_SIG_JUMP 1
 #endif
 
-/* To be able to use long doubles for 64-bit mixed arithmetics, we need
-   them at least 80 bits wide and we need roundl declared in math.h.
-   FIXME: Maybe substitute this by a more precise check in the future?  */
-#if (SIZEOF_LONG_DOUBLE >= 10) && defined (HAVE_ROUNDL)
-#  define OCTAVE_INT_USE_LONG_DOUBLE
-#  if (SIZEOF_LONG_DOUBLE < 16                                          \
-       && (defined __i386__ || defined __x86_64__) && defined __GNUC__)
-#    define OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED 1
-#  endif
-#endif
-
 /* oct-dlldefs.h */
 
 /* FIXME: GCC supports visibility attributes as well, even using the
