aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-09-07 10:52:47 +0200
committerEugen Wissner <belka@caraus.de>2026-09-07 10:52:47 +0200
commit0fada11e99da430e9a056e46da9f0e110df6c45c (patch)
treef6ec9d1c32e176ffd236c4e556c0fe8d1cd4ea9c
parent37f9bca3d0358192949f62573d163ce5362840c2 (diff)
downloadelna-0fada11e99da430e9a056e46da9f0e110df6c45c.tar.gz
Fix defer inside for loops
-rw-r--r--gcc/gcc/elna-generic.cc11
-rw-r--r--testsuite/runnable/for_defer.elna11
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.