changeset 32415:b747729c6695

Support nil value rhs in for loops in VM (bug #64775) When the rhs value in for loops is nil, it should not be assigned to lhs and the body should not be executed. * libinterp/parse-tree/pt-bytecode-vm.cc: rhs can be nil in for-loops. * test/compile/bytecode_for.m: Update tests
author Petter T. <petter.vilhelm@gmail.com>
date Mon, 16 Oct 2023 07:55:56 +0200
parents 385e847edfb7
children e9eb8975961e
files libinterp/parse-tree/pt-bytecode-vm.cc test/compile/bytecode_for.m
diffstat 2 files changed, 20 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/parse-tree/pt-bytecode-vm.cc	Sun Oct 15 16:50:47 2023 +0200
+++ b/libinterp/parse-tree/pt-bytecode-vm.cc	Mon Oct 16 07:55:56 2023 +0200
@@ -2750,7 +2750,7 @@
         else
           n = 0; // A e.g. 0x3 sized Cell gives no iterations, not 3
       }
-    else if (ov_range.is_scalar_type ())
+    else if (ov_range.is_scalar_type () || ov_range.is_undefined ())
       ;
     else
       TODO ("Unsupported for rhs type");
@@ -2775,7 +2775,7 @@
     (*sp++).i = -1;
 
     // For empty rhs just assign it to lhs
-    if (! n)
+    if (! n && ov_range.is_defined ())
       {
         // Slot from the for_cond that always follow a for_setup
         int slot;
@@ -3645,13 +3645,15 @@
 
   if (ov_rhs.is_undefined ())
     {
+      (*sp++).i = 1; // Need two native ints on the stack so they can be popped by the POP_N_INTS
+      (*sp++).i = 2; // after the for loop body.
       ip = code + target;
       DISPATCH ();
     }
 
   if (!ov_rhs.isstruct ())
     {
-      (*sp++).i = 1; // Need two native ints on the stack so they can be poped by the unwind.
+      (*sp++).i = 1; // Need two native ints on the stack so they can be popped by the unwind.
       (*sp++).i = 2;
       (*sp++).pee = new execution_exception {"error", "", "in statement 'for [X, Y] = VAL', VAL must be a structure"};
       (*sp++).i = static_cast<int> (error_type::EXECUTION_EXC);
--- a/test/compile/bytecode_for.m	Sun Oct 15 16:50:47 2023 +0200
+++ b/test/compile/bytecode_for.m	Mon Oct 16 07:55:56 2023 +0200
@@ -201,6 +201,21 @@
   for [val, key] = struct ()
     __printf_assert__ ("boo");
   end
+
+  % If rhs is an undefined value, the body should not be executed
+  % and the iteration variable not modified.
+  x = 1;
+  for x = __varval__ ("") % Use __varval__ to get an undefined value
+    __printf_assert__ ("booo");
+  end
+  assert (x == 1);
+
+  y = 2;
+  for [x, y] = __varval__ ("")
+    __printf_assert__ ("boo");
+  end
+  assert (x == 1);
+  assert (y == 2);
 end