diff --git a/releasenotes.md b/releasenotes.md index 3ff1a5116..2a7453115 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -47,6 +47,7 @@ - `return (any)&foo` would not be reported as an escaping variable if `foo` was a pointer or slice. - Incorrect error message when providing too many associated values for enum #1934. - Allow function types to have a calling convention. #1938 +- Issue with defer copying when triggered by break or continue. ### Stdlib changes - Added '%h' and '%H' for printing out binary data in hexadecimal using the formatter. diff --git a/src/compiler/copying.c b/src/compiler/copying.c index 1abd86950..d8a4e9c41 100644 --- a/src/compiler/copying.c +++ b/src/compiler/copying.c @@ -667,6 +667,7 @@ RETRY: if (ast->contbreak_stmt.is_resolved) { fixup_astid(c, &ast->contbreak_stmt.ast); + MACRO_COPY_ASTID(ast->contbreak_stmt.defers); } break; case AST_CASE_STMT: diff --git a/test/test_suite/statements/defer_in_defer3.c3t b/test/test_suite/statements/defer_in_defer3.c3t new file mode 100644 index 000000000..cef9b6a37 --- /dev/null +++ b/test/test_suite/statements/defer_in_defer3.c3t @@ -0,0 +1,46 @@ +// #target: macos-x64 +// #debuginfo: yes +module test; +extern fn void printf(char*,...); + +fn void test(int x) +{ + defer + { + do + { + defer { + x = 0; + printf("Hello\n"); + defer x = 1; + } + if (x < 100) break; + }; + } +} + +fn int main() +{ + test(0); + return 0; +} + +/* #expect: test.ll + + %x = alloca i32, align 4 + store i32 %0, ptr %x, align 4 + %1 = load i32, ptr %x, align 4, !dbg !15 + %lt = icmp slt i32 %1, 100, !dbg !15 + br i1 %lt, label %if.then, label %if.exit, !dbg !15 +if.then: ; preds = %entry + store i32 0, ptr %x, align 4, !dbg !19 + call void (ptr, ...) @printf(ptr @.str), !dbg !21 + store i32 1, ptr %x, align 4, !dbg !22 + br label %loop.exit, !dbg !22 +if.exit: ; preds = %entry + store i32 0, ptr %x, align 4, !dbg !24 + call void (ptr, ...) @printf(ptr @.str.1), !dbg !26 + store i32 1, ptr %x, align 4, !dbg !27 + br label %loop.exit, !dbg !27 +loop.exit: ; preds = %if.exit, %if.then + ret void, !dbg !27 \ No newline at end of file