Mercurial > octave
changeset 32228:355b4434b45d
VM: Fix problem with trivial ranges (patch #10362).
* libinterp/octave-value/ov-range.cc, libinterp/octave-value/ov-range.h
(ov_range<double>::could_be_trivial_range): Check that double precision values
can be represented as `int` data type.
* test/compile/bytecode.tst, test/compile/bytecode_for.m: Add tests with more
for-loop expressions.
author | Petter T. <petter.vilhelm@gmail.com> |
---|---|
date | Thu, 15 Jun 2023 16:03:54 +0200 |
parents | 1ce9acf56351 |
children | 9fddcbde0329 |
files | libinterp/octave-value/ov-range.cc libinterp/octave-value/ov-range.h test/compile/bytecode.tst test/compile/bytecode_for.m |
diffstat | 4 files changed, 58 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/octave-value/ov-range.cc Thu Aug 03 18:54:41 2023 +0200 +++ b/libinterp/octave-value/ov-range.cc Thu Jun 15 16:03:54 2023 +0200 @@ -995,11 +995,38 @@ if (n <= 1) return false; - double f = m_range.final_value (); - if (f > std::numeric_limits<int>::max() - || f < std::numeric_limits<int>::min()) + if (m_range.final_value () > std::numeric_limits<int>::max() || + m_range.final_value () < std::numeric_limits<int>::min()) + return false; + if (m_range.increment () > std::numeric_limits<int>::max() || + m_range.increment () < std::numeric_limits<int>::min()) + return false; + if (m_range.base () > std::numeric_limits<int>::max() || + m_range.base () < std::numeric_limits<int>::min()) + return false; + if (m_range.limit () > std::numeric_limits<int>::max() || + m_range.limit () < std::numeric_limits<int>::min()) + return false; + + if (std::isnan (m_range.final_value ())) return false; - if (std::isnan (f)) + if (std::isnan (m_range.increment ())) + return false; + if (std::isnan (m_range.base ())) + return false; + if (std::isnan (m_range.limit ())) + return false; + + if (static_cast<int> (m_range.final_value ()) != m_range.final_value ()) + return false; + if (static_cast<int> (m_range.increment ()) != m_range.increment ()) + return false; + if (static_cast<int> (m_range.base ()) != m_range.base ()) + return false; + if (static_cast<int> (m_range.limit ()) != m_range.limit ()) + return false; + + if (m_range.reverse ()) return false; return true;
--- a/libinterp/octave-value/ov-range.h Thu Aug 03 18:54:41 2023 +0200 +++ b/libinterp/octave-value/ov-range.h Thu Jun 15 16:03:54 2023 +0200 @@ -56,7 +56,7 @@ { public: - octave_trivial_range (octave_idx_type numel, double base, double incr) + octave_trivial_range (octave_idx_type numel, int base, int incr) : m_numel (numel), m_base (base), m_increment(incr) { } octave_trivial_range () {};
--- a/test/compile/bytecode.tst Thu Aug 03 18:54:41 2023 +0200 +++ b/test/compile/bytecode.tst Thu Jun 15 16:03:54 2023 +0200 @@ -87,7 +87,7 @@ %!test %! __enable_vm_eval__ (0, "local"); %! clear all -%! key = "1 2 3 4 4 1 3 5 5 4 3 2 1 1 1 4 2 2 16 4 3 3 256 3 2 1 double 1 3 size 2 size 1 2 4 size 2 size 1 double q size 1 size 1 w size 1 size 1 e size 1 size 1 char single single 5 1 11 2 12 key:a val:1 1val:1 key:b val:1 3val:2 4val:2 2key:c val:string "; +%! key = "1 2 3 4 4 1 3 5 5 1 4 4 4 3 2 1 1 0.200 0.300 0.400 0.400 0.300 0.200 0.100 0.000 0.000 NaN NaN NaN 1 4 2 2 16 4 3 3 256 3 2 1 double 1 3 size 2 size 1 2 4 size 2 size 1 double q size 1 size 1 w size 1 size 1 e size 1 size 1 char single single 5 1 11 2 12 key:a val:1 1val:1 key:b val:1 3val:2 4val:2 2key:c val:string "; %! %! __compile bytecode_for clear; %! bytecode_for ();
--- a/test/compile/bytecode_for.m Thu Aug 03 18:54:41 2023 +0200 +++ b/test/compile/bytecode_for.m Thu Jun 15 16:03:54 2023 +0200 @@ -11,11 +11,36 @@ end __printf_assert__ ("%d ", i); + for i = 1:3:5 + __printf_assert__ ("%d ", i); + end + __printf_assert__ ("%d ", i); + for i = 4:-1:1 __printf_assert__ ("%d ", i); end __printf_assert__ ("%d ", i); + for i = 0.2:0.1:0.4 + __printf_assert__ ("%3.3f ", i); + end + __printf_assert__ ("%3.3f ", i); + + for i = 0.3:-0.1:0 + __printf_assert__ ("%3.3f ", i); + end + __printf_assert__ ("%3.3f ", i); + + for i = 0:NaN:2 + __printf_assert__ ("%3.3f ", i); + end + for i = 0:1:NaN + __printf_assert__ ("%3.3f ", i); + end + for i = NaN:1:2 + __printf_assert__ ("%3.3f ", i); + end + for j = 1:4 break end