diff options
-rw-r--r-- | compiler.c | 18 | ||||
-rw-r--r-- | tests/custom/00_syntax/16_for_loop | 8 | ||||
-rw-r--r-- | tests/custom/03_bugs/24_compiler_local_for_loop_declaration | 18 |
3 files changed, 37 insertions, 7 deletions
@@ -1869,7 +1869,7 @@ uc_compiler_declare_internal(uc_compiler *compiler, size_t srcpos, const char *n } static void -uc_compiler_compile_local(uc_compiler *compiler) +uc_compiler_compile_declexpr(uc_compiler *compiler) { ssize_t slot; @@ -1899,7 +1899,12 @@ uc_compiler_compile_local(uc_compiler *compiler) } } while (uc_compiler_parse_match(compiler, TK_COMMA)); +} +static void +uc_compiler_compile_local(uc_compiler *compiler) +{ + uc_compiler_compile_declexpr(compiler); uc_compiler_parse_consume(compiler, TK_SCOL); } @@ -2218,8 +2223,15 @@ uc_compiler_compile_for_count(uc_compiler *compiler, bool local, uc_token *var) /* If followed by a comma, continue parsing expression */ if (uc_compiler_parse_match(compiler, TK_COMMA)) { - uc_compiler_compile_expression(compiler); - uc_compiler_emit_insn(compiler, 0, I_POP); + /* Is a continuation of a declaration list... */ + if (local) { + uc_compiler_compile_declexpr(compiler); + } + /* ... otherwise an unrelated expression */ + else { + uc_compiler_compile_expression(compiler); + uc_compiler_emit_insn(compiler, 0, I_POP); + } } } /* ... otherwise try parsing an entire expression (which might be absent) */ diff --git a/tests/custom/00_syntax/16_for_loop b/tests/custom/00_syntax/16_for_loop index 67edc21..b206b07 100644 --- a/tests/custom/00_syntax/16_for_loop +++ b/tests/custom/00_syntax/16_for_loop @@ -220,10 +220,10 @@ rejected. -- Expect stderr -- Syntax error: Unexpected token Expecting ';' -In line 2, byte 24: +In line 2, byte 19: ` for (let x, y, z in {})` - Near here ----------------^ + Near here -----------^ -- End -- @@ -241,10 +241,10 @@ Ensure that assignments in for-in loop expressions are rejected. -- Expect stderr -- Syntax error: Unexpected token Expecting ';' -In line 2, byte 25: +In line 2, byte 20: ` for (let x = 1, y in {})` - Near here -----------------^ + Near here ------------^ -- End -- diff --git a/tests/custom/03_bugs/24_compiler_local_for_loop_declaration b/tests/custom/03_bugs/24_compiler_local_for_loop_declaration new file mode 100644 index 0000000..aafde55 --- /dev/null +++ b/tests/custom/03_bugs/24_compiler_local_for_loop_declaration @@ -0,0 +1,18 @@ +When compiling a for-loop local variable initializer expression, the compiler +incorrectly treated subsequent declarations as global variable assignments, +triggering reference error exceptions in strict mode. + +-- Expect stdout -- +1 +-- End -- + +-- Testcase -- +{% + "use strict"; + + // The initializer expression below was incorrectly interpreted as + // `let x = 0; y = 1` instead of the correct `let ..., y = 1`. + for (let x = 0, y = 1; x < 1; x++) + print(y, "\n"); +%} +-- End -- |