Mercurial > octave
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