diff --git a/compiler.c b/compiler.c index 3b2d585e..73e5f5b9 100644 --- a/compiler.c +++ b/compiler.c @@ -2990,7 +2990,7 @@ uc_compiler_compile_for_count(uc_compiler_t *compiler, bool local, uc_token_t *p uc_compiler_parse_consume(compiler, TK_RPAREN); /* if we have a condition, jump back to it, else continue to the loop body */ - if (cond_off) + if (test_off) uc_compiler_emit_jmp_dest(compiler, 0, cond_off); /* back patch skip address */ diff --git a/tests/custom/99_bugs/58_for_loop_condition_at_function_start b/tests/custom/99_bugs/58_for_loop_condition_at_function_start new file mode 100644 index 00000000..91ec3b42 --- /dev/null +++ b/tests/custom/99_bugs/58_for_loop_condition_at_function_start @@ -0,0 +1,38 @@ +A counting for loop without an initializer that opened a function body +placed its condition at bytecode offset 0, which the compiler mistook +for an absent condition. The loop then never jumped back to the test +and kept running after the condition had turned false. + +-- Testcase -- +{% + function count_down(n) { + for (; n > 0; n--) { + if (n < -2) + return "runaway"; + + print(n, "\n"); + } + + return "done"; + } + + function walk(n) { + for (; n > 1; n = int(n / 2)) + if (n == 0) + return "runaway"; + + return n; + } + + print(count_down(3), "\n"); + print(walk(8), "\n"); +%} +-- End -- + +-- Expect stdout -- +3 +2 +1 +done +1 +-- End --