From 316982fb8f6ebb429b1fbdaeabc4fee518f4d36e Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Wed, 19 Jun 2024 01:17:43 +0200 Subject: [PATCH] Added test and removed todo. --- src/compiler/sema_stmts.c | 7 +- test/test_suite/defer/defer_nextcase.c3t | 182 +++++++++++++++++++++++ 2 files changed, 184 insertions(+), 5 deletions(-) create mode 100644 test/test_suite/defer/defer_nextcase.c3t diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index 62d416a9e..2ec3d5f8c 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -2047,7 +2047,6 @@ static bool sema_analyse_nextcase_stmt(SemaContext *context, Ast *statement) return false; } - // TODO test that nextcase out of a switch using label correctly creates defers. Ast *parent = context->next_switch; if (statement->nextcase_stmt.label.name) { @@ -2057,14 +2056,12 @@ static bool sema_analyse_nextcase_stmt(SemaContext *context, Ast *statement) AstKind kind = parent->ast_kind; if (kind != AST_SWITCH_STMT && kind != AST_IF_CATCH_SWITCH_STMT) { - SEMA_ERROR(&statement->nextcase_stmt.label, "Expected the label to match a 'switch' or 'if-catch' statement."); - return false; + RETURN_SEMA_ERROR(&statement->nextcase_stmt.label, "Expected the label to match a 'switch' or 'if-catch' statement."); } } if (!parent) { - SEMA_ERROR(statement, "No matching switch could be found."); - return false; + RETURN_SEMA_ERROR(statement, "No matching switch could be found."); } // Handle jump to default. diff --git a/test/test_suite/defer/defer_nextcase.c3t b/test/test_suite/defer/defer_nextcase.c3t new file mode 100644 index 000000000..277dc6688 --- /dev/null +++ b/test/test_suite/defer/defer_nextcase.c3t @@ -0,0 +1,182 @@ +// #target: macos-aarch64 +module test; +import std; + +fn void print(String y) +{ + io::printn(y); +} + +fn void foo(int x) +{ + print("---"); + switch FOO: (x) + { + case 0: + defer print("0.0"); + switch (x) + { + case 0: + defer print("0"); + nextcase FOO: 3; + } + print("Err"); + case 3: + x = 3; + defer print("3.0"); + switch (x) + { + case 3: + defer print("3"); + int j = 2; + nextcase FOO: j; + } + print("Err"); + case 2: + x = 2; + defer print("2.0"); + switch (x) + { + case 2: + defer print("2"); + break FOO; + } + break; + } +} +fn int main() +{ + foo(0); + foo(2); + return 0; +} +/* #expect: test.ll + +define void @test.foo(i32 %0) #0 { +entry: + %x = alloca i32, align 4 + %taddr = alloca %"char[]", align 8 + %switch = alloca i32, align 4 + %switch1 = alloca i32, align 4 + %taddr4 = alloca %"char[]", align 8 + %taddr5 = alloca %"char[]", align 8 + %taddr6 = alloca %"char[]", align 8 + %taddr7 = alloca %"char[]", align 8 + %switch9 = alloca i32, align 4 + %j = alloca i32, align 4 + %taddr12 = alloca %"char[]", align 8 + %taddr13 = alloca %"char[]", align 8 + %taddr15 = alloca %"char[]", align 8 + %taddr16 = alloca %"char[]", align 8 + %switch18 = alloca i32, align 4 + %taddr21 = alloca %"char[]", align 8 + %taddr22 = alloca %"char[]", align 8 + %taddr24 = alloca %"char[]", align 8 + store i32 %0, ptr %x, align 4 + store %"char[]" { ptr @.str, i64 3 }, ptr %taddr, align 8 + %1 = load [2 x i64], ptr %taddr, align 8 + call void @test.print([2 x i64] %1) + %2 = load i32, ptr %x, align 4 + store i32 %2, ptr %switch, align 4 + br label %switch.entry + +switch.entry: ; preds = %switch.case11, %entry + %3 = load i32, ptr %switch, align 4 + switch i32 %3, label %switch.exit25 [ + i32 0, label %switch.case + i32 3, label %switch.case8 + i32 2, label %switch.case17 + ] + +switch.case: ; preds = %switch.entry + %4 = load i32, ptr %x, align 4 + store i32 %4, ptr %switch1, align 4 + br label %switch.entry2 + +switch.entry2: ; preds = %switch.case + %5 = load i32, ptr %switch1, align 4 + switch i32 %5, label %switch.exit [ + i32 0, label %switch.case3 + ] + +switch.case3: ; preds = %switch.entry2 + store %"char[]" { ptr @.str.1, i64 1 }, ptr %taddr4, align 8 + %6 = load [2 x i64], ptr %taddr4, align 8 + call void @test.print([2 x i64] %6) + store %"char[]" { ptr @.str.2, i64 3 }, ptr %taddr5, align 8 + %7 = load [2 x i64], ptr %taddr5, align 8 + call void @test.print([2 x i64] %7) + br label %switch.case8 + +switch.exit: ; preds = %switch.entry2 + store %"char[]" { ptr @.str.3, i64 3 }, ptr %taddr6, align 8 + %8 = load [2 x i64], ptr %taddr6, align 8 + call void @test.print([2 x i64] %8) + store %"char[]" { ptr @.str.4, i64 3 }, ptr %taddr7, align 8 + %9 = load [2 x i64], ptr %taddr7, align 8 + call void @test.print([2 x i64] %9) + br label %switch.exit25 + +switch.case8: ; preds = %switch.entry, %switch.case3 + store i32 3, ptr %x, align 4 + %10 = load i32, ptr %x, align 4 + store i32 %10, ptr %switch9, align 4 + br label %switch.entry10 + +switch.entry10: ; preds = %switch.case8 + %11 = load i32, ptr %switch9, align 4 + switch i32 %11, label %switch.exit14 [ + i32 3, label %switch.case11 + ] + +switch.case11: ; preds = %switch.entry10 + store i32 2, ptr %j, align 4 + %12 = load i32, ptr %j, align 4 + store i32 %12, ptr %switch, align 4 + store %"char[]" { ptr @.str.5, i64 1 }, ptr %taddr12, align 8 + %13 = load [2 x i64], ptr %taddr12, align 8 + call void @test.print([2 x i64] %13) + store %"char[]" { ptr @.str.6, i64 3 }, ptr %taddr13, align 8 + %14 = load [2 x i64], ptr %taddr13, align 8 + call void @test.print([2 x i64] %14) + br label %switch.entry + +switch.exit14: ; preds = %switch.entry10 + store %"char[]" { ptr @.str.7, i64 3 }, ptr %taddr15, align 8 + %15 = load [2 x i64], ptr %taddr15, align 8 + call void @test.print([2 x i64] %15) + store %"char[]" { ptr @.str.8, i64 3 }, ptr %taddr16, align 8 + %16 = load [2 x i64], ptr %taddr16, align 8 + call void @test.print([2 x i64] %16) + br label %switch.exit25 + +switch.case17: ; preds = %switch.entry + store i32 2, ptr %x, align 4 + %17 = load i32, ptr %x, align 4 + store i32 %17, ptr %switch18, align 4 + br label %switch.entry19 + +switch.entry19: ; preds = %switch.case17 + %18 = load i32, ptr %switch18, align 4 + switch i32 %18, label %switch.exit23 [ + i32 2, label %switch.case20 + ] + +switch.case20: ; preds = %switch.entry19 + store %"char[]" { ptr @.str.9, i64 1 }, ptr %taddr21, align 8 + %19 = load [2 x i64], ptr %taddr21, align 8 + call void @test.print([2 x i64] %19) + store %"char[]" { ptr @.str.10, i64 3 }, ptr %taddr22, align 8 + %20 = load [2 x i64], ptr %taddr22, align 8 + call void @test.print([2 x i64] %20) + br label %switch.exit25 + +switch.exit23: ; preds = %switch.entry19 + store %"char[]" { ptr @.str.11, i64 3 }, ptr %taddr24, align 8 + %21 = load [2 x i64], ptr %taddr24, align 8 + call void @test.print([2 x i64] %21) + br label %switch.exit25 + +switch.exit25: ; preds = %switch.exit23, %switch.case20, %switch.exit14, %switch.exit, %switch.entry + ret void +}