diff libinterp/octave-value/ov.cc @ 29410:65979d33f147

Emit error if integer/floating point inputs to colon operator are incompatible (bug #59899). * ov.cc (make_range<double>, make_range<float>): Template specializations for cases where all inputs are floating point. * ov.cc (make_range<T>): In template used for integers, convert base, increment, and limit inputs both to type T and to type double. Compare values and emit an error if integer value T and double value do not agree. * range.tst: Add BIST tests for mixed integer/floating point errors.
author Rik <rik@octave.org>
date Fri, 05 Mar 2021 08:44:31 -0800
parents c75996cbe3ba
children e88444be8468
line wrap: on
line diff
--- a/libinterp/octave-value/ov.cc	Thu Mar 04 10:02:58 2021 -0500
+++ b/libinterp/octave-value/ov.cc	Fri Mar 05 08:44:31 2021 -0800
@@ -2969,6 +2969,7 @@
     return get_colon_op_type (typ, limit.builtin_type ());
   }
 
+  // Templated version used for various integer types (int8, uint16, ...)
   template <typename T>
   octave_value
   make_range (const octave_value& base, const octave_value& increment,
@@ -2977,9 +2978,22 @@
     if (base.isempty () || increment.isempty () || limit.isempty ())
       return octave_value (range<T> (), for_cmd_expr);
 
+    double dval;
+
     T base_val = octave_value_extract<T> (base);
+    dval = base.double_value ();
+    if (base_val != dval)
+      error ("colon operator lower bound invalid (not an integer or out of range for given integer type)");
+
     T increment_val = octave_value_extract<T> (increment);
+    dval = increment.double_value ();
+    if (increment_val != dval)
+      error ("colon operator increment invalid (not an integer or out of range for given integer type)");
+
     T limit_val = octave_value_extract<T> (limit);
+    dval = limit.double_value ();
+    if (limit_val != dval)
+      error ("colon operator upper bound invalid (not an integer or out of range for given integer type)");
 
     range<T> r (base_val, increment_val, limit_val);
 
@@ -2988,6 +3002,40 @@
 
   template <>
   octave_value
+  make_range<double> (const octave_value& base, const octave_value& increment,
+                      const octave_value& limit, bool for_cmd_expr)
+  {
+    if (base.isempty () || increment.isempty () || limit.isempty ())
+      return octave_value (range<double> (), for_cmd_expr);
+
+    double base_val = base.double_value ();
+    double increment_val = increment.double_value ();
+    double limit_val = limit.double_value ();
+
+    range<double> r (base_val, increment_val, limit_val);
+
+    return octave_value (r, for_cmd_expr);
+  }
+
+  template <>
+  octave_value
+  make_range<float> (const octave_value& base, const octave_value& increment,
+                     const octave_value& limit, bool for_cmd_expr)
+  {
+    if (base.isempty () || increment.isempty () || limit.isempty ())
+      return octave_value (range<float> (), for_cmd_expr);
+
+    float base_val = base.float_value ();
+    float increment_val = increment.float_value ();
+    float limit_val = limit.float_value ();
+
+    range<float> r (base_val, increment_val, limit_val);
+
+    return octave_value (r, for_cmd_expr);
+  }
+
+  template <>
+  octave_value
   make_range<char> (const octave_value& base, const octave_value& increment,
                     const octave_value& limit, bool for_cmd_expr)
   {
@@ -3044,7 +3092,7 @@
           {
             octave_value_list tmp2 = interp.feval (fcn, tmp1, 1);
 
-            return tmp2 (0);
+            return tmp2(0);
           }
       }