changeset 32095:28ef2991fb5a

Emit warning about infinite loop if for loop range starts with infinite value. * pt-eval.cc (execute_range_loop): Check base of range, in addition to limit of range, for infinite value and emit warning if found. * for.tst: Add tests for new behavior. Recode tests so that they don't emit warnings if file 'for.tst' is tested outside of test suite.
author Rik <rik@octave.org>
date Wed, 17 May 2023 20:29:17 -0700
parents f3d12359f0e4
children 501730f07abc
files libinterp/parse-tree/pt-eval.cc test/for.tst
diffstat 2 files changed, 42 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/parse-tree/pt-eval.cc	Sat May 13 15:15:51 2023 +0200
+++ b/libinterp/parse-tree/pt-eval.cc	Wed May 17 20:29:17 2023 -0700
@@ -3010,7 +3010,7 @@
 {
   octave_idx_type steps = rng.numel ();
 
-  if (math::isinf (rng.limit ()))
+  if (math::isinf (rng.limit ()) || math::isinf (rng.base ()))
     warning_with_id ("Octave:infinite-loop",
                      "FOR loop limit is infinite, will stop after %"
                      OCTAVE_IDX_TYPE_FORMAT " steps", steps);
--- a/test/for.tst	Sat May 13 15:15:51 2023 +0200
+++ b/test/for.tst	Wed May 17 20:29:17 2023 -0700
@@ -169,24 +169,51 @@
 %!
 %! fail ("for i = 0:-1:-inf; break; end", "warning",
 %!       "FOR loop limit is infinite");
+%!
+%! fail ("for i = inf:-1:1; break; end", "warning",
+%!       "FOR loop limit is infinite");
+%!
+%! fail ("for i = -inf:+1:1; break; end", "warning",
+%!       "FOR loop limit is infinite");
 
 %!test <*45143>
 %! warning ("on", "Octave:infinite-loop", "local");
-%! k = 0;
-%! for i = 1:Inf
-%!   if (++k > 10)
-%!     break;
-%!   endif
-%! endfor
-%! assert (i, 11);
+%
+%! code = cstrcat ("k = 0;               ",
+%!                 "for i = 1:Inf;       ",
+%!                 "  if (++k > 10);     ",
+%!                 "    break;           ",
+%!                 "  endif;             ",
+%!                 "endfor;              ",
+%!                 "assert (i, 11);      ");
+%! fail (code, "warning", "FOR loop limit is infinite");
 %!
-%! k = 0;
-%! for i = -1:-1:-Inf
-%!   if (++k > 10)
-%!     break;
-%!   endif
-%! endfor
-%! assert (i, -11);
+%! code = cstrcat ("k = 0;               ",
+%!                 "for i = -1:-1:-Inf;  ",
+%!                 "  if (++k > 10);     ",
+%!                 "    break;           ",
+%!                 "  endif;             ",
+%!                 "endfor;              ",
+%!                 "assert (i, -11);     ");
+%! fail (code, "warning", "FOR loop limit is infinite");
+%!
+%! code = cstrcat ("k = 0;               ",
+%!                 "for i = Inf:-1:1;    ",
+%!                 "  if (++k > 10);     ",
+%!                 "    break;           ",
+%!                 "  endif;             ",
+%!                 "endfor;              ",
+%!                 "assert (i, Inf);     ");
+%! fail (code, "warning", "FOR loop limit is infinite");
+%!
+%! code = cstrcat ("k = 0;               ",
+%!                 "for i = -Inf:+1:1;   ",
+%!                 "  if (++k > 10);     ",
+%!                 "    break;           ",
+%!                 "  endif;             ",
+%!                 "endfor;              ",
+%!                 "assert (i, -Inf);    ");
+%! fail (code, "warning", "FOR loop limit is infinite");
 %!
 %! k = 0;
 %! for i = 1:-Inf