diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-09-07 10:52:47 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-09-07 10:52:47 +0200 |
| commit | 0fada11e99da430e9a056e46da9f0e110df6c45c (patch) | |
| tree | f6ec9d1c32e176ffd236c4e556c0fe8d1cd4ea9c | |
| parent | 37f9bca3d0358192949f62573d163ce5362840c2 (diff) | |
| download | elna-0fada11e99da430e9a056e46da9f0e110df6c45c.tar.gz | |
Fix defer inside for loops
| -rw-r--r-- | gcc/gcc/elna-generic.cc | 11 | ||||
| -rw-r--r-- | testsuite/runnable/for_defer.elna | 11 |
2 files changed, 18 insertions, 4 deletions
diff --git a/gcc/gcc/elna-generic.cc b/gcc/gcc/elna-generic.cc index b786688..34ae5ee 100644 --- a/gcc/gcc/elna-generic.cc +++ b/gcc/gcc/elna-generic.cc @@ -958,10 +958,13 @@ namespace elna::gcc auto [check_label, end_label] = build_loop_head(control_variable_declaration, end_pointer, LT_EXPR, location); - for (auto *body_statement : statement->body) - { - body_statement->accept(this); - } + // The body gets its own scope, so that defer statements in it are run on + // every iteration and not once for the whole loop. + enter_scope(); + visit_statements(statement->body); + tree body_binding = leave_scope(); + append_statement(body_binding); + tree pointer_plus = do_pointer_arithmetic(boot::binary_operator::sum, control_variable_declaration, elna_word_one_node, location); append_statement(build2(MODIFY_EXPR, void_type_node, control_variable_declaration, pointer_plus)); diff --git a/testsuite/runnable/for_defer.elna b/testsuite/runnable/for_defer.elna new file mode 100644 index 0000000..6c9291b --- /dev/null +++ b/testsuite/runnable/for_defer.elna @@ -0,0 +1,11 @@ +var + array: [2]Int := [0, 0] + +begin + for x of array do + defer + x^ := 1 + end + end; + assert(array = [1, 1]) +end. |
