Mercurial > octave
changeset 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 | d6908a010a89 |
children | f26f9dbfb2c5 |
files | libinterp/octave-value/ov.cc test/range.tst |
diffstat | 2 files changed, 56 insertions(+), 9 deletions(-) [+] |
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); } }
--- a/test/range.tst Thu Mar 04 10:02:58 2021 -0500 +++ b/test/range.tst Fri Mar 05 08:44:31 2021 -0800 @@ -483,11 +483,10 @@ %!error <invalid types found in range> (1:1:{5}) %!error <incompatible types found in range> (int8(1):int16(1):5) %!error <incompatible types found in range> (int8(1):1:int16(5)) -## Convert to ordinary %!error test when this behavior is coded -%!xtest <59899> -%! fail ('(int8(1):0.4:5)', 'floating point values must be integers when used with integer data types'); -%! fail ('(int8(1):1:5.5)', 'floating point values must be integers when used with integer data types'); -%!xtest <59899> -%! fail ('(uint8(5):-1:1)', 'start, increment, and end values must be within the range of the integer data type'); -%! fail ('(-5:1:uint8(1)', 'start, increment, and end values must be within the range of the integer data type'); -%! fail ('(uint8(255):1:260', 'start, increment, and end values must be within the range of the integer data type'); +## Tests with mixed integer/floating point values +%!error <colon operator lower bound invalid> (1.5:uint8(1):5) +%!error <colon operator lower bound invalid> (-1:uint8(1):5) +%!error <colon operator increment invalid> (uint8(1):1.5:5) +%!error <colon operator increment invalid> (uint8(1):-1:5) +%!error <colon operator upper bound invalid> (uint8(1):1:5.5) +%!error <colon operator upper bound invalid> (uint8(1):1:256)