From b0b1eaeb6de20bd364a471132cd2e29a21b5e738 Mon Sep 17 00:00:00 2001 From: Dmitrii Maganov Date: Thu, 23 Feb 2023 04:13:09 +0200 Subject: [PATCH] GDScript: Fix parsing unexpected break/continue in lambda --- modules/gdscript/gdscript_parser.cpp | 13 +++++++++++++ .../scripts/parser/errors/bad_continue_in_lambda.gd | 5 +++++ .../parser/errors/bad_continue_in_lambda.out | 2 ++ .../parser/features/good_continue_in_lambda.gd | 13 +++++++++++++ .../parser/features/good_continue_in_lambda.out | 2 ++ 5 files changed, 35 insertions(+) create mode 100644 modules/gdscript/tests/scripts/parser/errors/bad_continue_in_lambda.gd create mode 100644 modules/gdscript/tests/scripts/parser/errors/bad_continue_in_lambda.out create mode 100644 modules/gdscript/tests/scripts/parser/features/good_continue_in_lambda.gd create mode 100644 modules/gdscript/tests/scripts/parser/features/good_continue_in_lambda.out diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index b32313dad4d..c402b63f7bc 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -3138,6 +3138,14 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_lambda(ExpressionNode *p_p bool previous_in_lambda = in_lambda; in_lambda = true; + // Save break/continue state. + bool could_break = can_break; + bool could_continue = can_continue; + + // Disallow break/continue. + can_break = false; + can_continue = false; + function->body = parse_suite("lambda declaration", body, true); complete_extents(function); complete_extents(lambda); @@ -3155,6 +3163,11 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_lambda(ExpressionNode *p_p current_function = previous_function; in_lambda = previous_in_lambda; lambda->function = function; + + // Reset break/continue state. + can_break = could_break; + can_continue = could_continue; + return lambda; } diff --git a/modules/gdscript/tests/scripts/parser/errors/bad_continue_in_lambda.gd b/modules/gdscript/tests/scripts/parser/errors/bad_continue_in_lambda.gd new file mode 100644 index 00000000000..319c1801c03 --- /dev/null +++ b/modules/gdscript/tests/scripts/parser/errors/bad_continue_in_lambda.gd @@ -0,0 +1,5 @@ +func test(): + for index in range(0, 1): + var lambda := func(): + continue + print('not ok') diff --git a/modules/gdscript/tests/scripts/parser/errors/bad_continue_in_lambda.out b/modules/gdscript/tests/scripts/parser/errors/bad_continue_in_lambda.out new file mode 100644 index 00000000000..262dfbc09b6 --- /dev/null +++ b/modules/gdscript/tests/scripts/parser/errors/bad_continue_in_lambda.out @@ -0,0 +1,2 @@ +GDTEST_PARSER_ERROR +Cannot use "continue" outside of a loop. diff --git a/modules/gdscript/tests/scripts/parser/features/good_continue_in_lambda.gd b/modules/gdscript/tests/scripts/parser/features/good_continue_in_lambda.gd new file mode 100644 index 00000000000..2fa45c1d7df --- /dev/null +++ b/modules/gdscript/tests/scripts/parser/features/good_continue_in_lambda.gd @@ -0,0 +1,13 @@ +func test(): + var i_string := '' + for i in 3: + if i == 1: continue + var lambda := func(): + var j_string := '' + for j in 3: + if j == 1: continue + j_string += str(j) + return j_string + i_string += lambda.call() + assert(i_string == '0202') + print('ok') diff --git a/modules/gdscript/tests/scripts/parser/features/good_continue_in_lambda.out b/modules/gdscript/tests/scripts/parser/features/good_continue_in_lambda.out new file mode 100644 index 00000000000..1b47ed10dc0 --- /dev/null +++ b/modules/gdscript/tests/scripts/parser/features/good_continue_in_lambda.out @@ -0,0 +1,2 @@ +GDTEST_OK +ok