Mercurial > octave
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); } }