diff --git a/lib/std/io/stream.c3 b/lib/std/io/stream.c3 index 185c9467e..c62373066 100644 --- a/lib/std/io/stream.c3 +++ b/lib/std/io/stream.c3 @@ -112,8 +112,8 @@ macro usz! read_using_read_byte(s, char[] buffer) char! c = s.read_byte(); if (catch err = c) { - case IoError.EOF: return len; - default: return err?; + if (err == IoError.EOF) return len; + return err?; } *cptr = c; len++; @@ -173,8 +173,8 @@ macro usz! copy_through_buffer(InStream in, OutStream dst, char[] buffer) @local usz! len = in.read(buffer); if (catch err = len) { - case IoError.EOF: return total_copied; - default: return err?; + if (err == IoError.EOF) return total_copied; + return err?; } if (!len) return total_copied; usz written = dst.write(buffer[:len])!; @@ -201,10 +201,8 @@ macro usz! read_varint(stream, x_ptr) char! c = stream.read_byte(); if (catch err = c) { - case IoError.EOF: - return IoError.UNEXPECTED_EOF?; - default: - return err?; + if (err == IoError.EOF) return IoError.UNEXPECTED_EOF?; + return err?; } n++; if (c & 0x80 == 0) diff --git a/lib/std/io/stream/multireader.c3 b/lib/std/io/stream/multireader.c3 index 83404152d..1fab083e2 100644 --- a/lib/std/io/stream/multireader.c3 +++ b/lib/std/io/stream/multireader.c3 @@ -49,15 +49,13 @@ fn usz! MultiReader.read(&self, char[] bytes) @dynamic usz! n = r.read(bytes); if (catch err = n) { - case IoError.EOF: - self.index++; - if (self.index >= self.readers.len) - { - return IoError.EOF?; - } - return self.read(bytes); - default: - return err?; + if (err != IoError.EOF) return err?; + self.index++; + if (self.index >= self.readers.len) + { + return IoError.EOF?; + } + return self.read(bytes); } return n; } diff --git a/lib/std/io/stream/scanner.c3 b/lib/std/io/stream/scanner.c3 index 16242153b..5396aabc6 100644 --- a/lib/std/io/stream/scanner.c3 +++ b/lib/std/io/stream/scanner.c3 @@ -92,10 +92,8 @@ macro usz! Scanner.refill(&self, buf) @private usz! n = self.wrapped_stream.read(buf); if (catch err = n) { - case IoError.EOF: - return SearchResult.MISSING?; - default: - return err?; + if (err == IoError.EOF) return SearchResult.MISSING?; + return err?; } return n; } diff --git a/releasenotes.md b/releasenotes.md index b1d4520de..0ef9b90b2 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -23,6 +23,7 @@ - `$switch` "()" replaced by trailing ":" `$switch ($Type)` -> `$switch $Type:` - Empty `$switch` requires trailing ":" `$switch` -> `$switch:` - Change `@return!` syntax to require ":" after faults. +- Remove `if (catch foo) { case ... }` syntax. ### Fixes - Fix address sanitizer to work on MachO targets (e.g. MacOS). diff --git a/src/compiler/c_codegen.c b/src/compiler/c_codegen.c index 28688eb68..41d62eaba 100644 --- a/src/compiler/c_codegen.c +++ b/src/compiler/c_codegen.c @@ -795,8 +795,6 @@ static void c_emit_stmt(GenContext *c, Ast *stmt) break; case AST_FOREACH_STMT: break; - case AST_IF_CATCH_SWITCH_STMT: - break; case AST_IF_STMT: break; case AST_NOP_STMT: diff --git a/src/compiler/copying.c b/src/compiler/copying.c index 7838e585f..f8f7112a0 100644 --- a/src/compiler/copying.c +++ b/src/compiler/copying.c @@ -762,7 +762,6 @@ RETRY: MACRO_COPY_ASTID(ast->return_stmt.cleanup_fail); break; case AST_SWITCH_STMT: - case AST_IF_CATCH_SWITCH_STMT: copy_reg_ref(c, source, ast); SCOPE_FIXUP_START copy_flow(c, ast); diff --git a/src/compiler/enums.h b/src/compiler/enums.h index 4fae37004..cfe44edd8 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -215,7 +215,6 @@ typedef enum AST_EXPR_STMT, AST_FOREACH_STMT, AST_FOR_STMT, - AST_IF_CATCH_SWITCH_STMT, AST_IF_STMT, AST_NEXTCASE_STMT, AST_NOP_STMT, @@ -559,7 +558,6 @@ typedef enum typedef enum { COND_TYPE_UNWRAP_BOOL, - COND_TYPE_UNWRAP, COND_TYPE_EVALTYPE_VALUE, } CondType; diff --git a/src/compiler/llvm_codegen_stmt.c b/src/compiler/llvm_codegen_stmt.c index d2964250c..20e452d8c 100644 --- a/src/compiler/llvm_codegen_stmt.c +++ b/src/compiler/llvm_codegen_stmt.c @@ -398,20 +398,6 @@ static void llvm_emit_if_stmt(GenContext *c, Ast *ast) bool exit_in_use = true; - if (then_body->ast_kind == AST_IF_CATCH_SWITCH_STMT) - { - llvm_emit_cond(c, &be_value, cond, false); - llvm_value_rvalue(c, &be_value); - BEValue comp; - llvm_emit_int_comp_zero(c, &comp, &be_value, BINARYOP_NE); - llvm_emit_cond_br(c, &comp, then_block, else_block); - llvm_emit_br(c, then_block); - llvm_emit_block(c, then_block); - llvm_emit_switch_body(c, &be_value, then_body, false); - llvm_emit_br(c, exit_block); - goto EMIT_ELSE; - } - llvm_emit_cond(c, &be_value, cond, true); llvm_value_rvalue(c, &be_value); @@ -459,7 +445,6 @@ static void llvm_emit_if_stmt(GenContext *c, Ast *ast) llvm_emit_br(c, exit_block); } - EMIT_ELSE: // Emit the 'else' branch if present. if (else_block != exit_block) { @@ -940,7 +925,7 @@ static void llvm_emit_switch_jump_table(GenContext *c, static void llvm_emit_switch_body(GenContext *c, BEValue *switch_value, Ast *switch_ast, bool is_typeid) { bool is_if_chain = switch_ast->switch_stmt.flow.if_chain; - Type *switch_type = switch_ast->ast_kind == AST_IF_CATCH_SWITCH_STMT ? type_lowering(type_anyfault) : switch_value->type; + Type *switch_type = switch_value->type; Ast **cases = switch_ast->switch_stmt.cases; ArraySize case_count = vec_size(cases); if (!case_count) @@ -1094,7 +1079,6 @@ void llvm_emit_break(GenContext *c, Ast *ast) case AST_FOR_STMT: jump = jump_target->for_stmt.codegen.exit_block; break; - case AST_IF_CATCH_SWITCH_STMT: case AST_SWITCH_STMT: jump = jump_target->switch_stmt.codegen.exit_block; break; @@ -1646,7 +1630,6 @@ void llvm_emit_stmt(GenContext *c, Ast *ast) switch (ast->ast_kind) { case AST_POISONED: - case AST_IF_CATCH_SWITCH_STMT: case AST_FOREACH_STMT: case AST_CONTRACT: case AST_ASM_STMT: diff --git a/src/compiler/parse_stmt.c b/src/compiler/parse_stmt.c index dbc733e1b..e906a449b 100644 --- a/src/compiler/parse_stmt.c +++ b/src/compiler/parse_stmt.c @@ -602,8 +602,7 @@ static inline Ast* parse_while_stmt(ParseContext *c) /** - * if_stmt ::= IF optional_label '(' cond ')' switch_body (ELSE compound_stmt)? - * | IF optional_label '(' cond ')' compound_stmt (ELSE compound_stmt)? + * if_stmt ::= IF optional_label '(' cond ')' compound_stmt (ELSE compound_stmt)? * | IF optional_label '(' cond ')' statement */ static inline Ast* parse_if_stmt(ParseContext *c) @@ -615,25 +614,13 @@ static inline Ast* parse_if_stmt(ParseContext *c) ASSIGN_EXPRID_OR_RET(if_ast->if_stmt.cond, parse_cond(c), poisoned_ast); unsigned row = c->span.row; CONSUME_OR_RET(TOKEN_RPAREN, poisoned_ast); - // Special case, we might have if ( ) { case ... } - if (tok_is(c, TOKEN_LBRACE) && (peek(c) == TOKEN_CASE || peek(c) == TOKEN_DEFAULT)) - { - Ast *stmt = new_ast(AST_IF_CATCH_SWITCH_STMT, c->span); - Ast **cases = NULL; - if (!parse_switch_body(c, &cases, TOKEN_CASE, TOKEN_DEFAULT)) return poisoned_ast; - stmt->switch_stmt.cases = cases; - if_ast->if_stmt.then_body = astid(stmt); - } - else + unsigned next_row = c->span.row; + ASSIGN_ASTID_OR_RET(if_ast->if_stmt.then_body, parse_stmt(c), poisoned_ast); + if (row != next_row && astptr(if_ast->if_stmt.then_body)->ast_kind != AST_COMPOUND_STMT) { - unsigned next_row = c->span.row; - ASSIGN_ASTID_OR_RET(if_ast->if_stmt.then_body, parse_stmt(c), poisoned_ast); - if (row != next_row && astptr(if_ast->if_stmt.then_body)->ast_kind != AST_COMPOUND_STMT) - { - // Poison it and pick it up later. - ast_poison(astptr(if_ast->if_stmt.then_body)); - } + // Poison it and pick it up later. + ast_poison(astptr(if_ast->if_stmt.then_body)); } if (try_consume(c, TOKEN_ELSE)) { diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index 93624e188..cd7115fcb 100755 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -3765,7 +3765,6 @@ static inline bool sema_check_body_const(SemaContext *context, Ast *body) case AST_DEFER_STMT: case AST_FOR_STMT: case AST_FOREACH_STMT: - case AST_IF_CATCH_SWITCH_STMT: case AST_IF_STMT: case AST_BLOCK_EXIT_STMT: case AST_SWITCH_STMT: diff --git a/src/compiler/sema_liveness.c b/src/compiler/sema_liveness.c index 66ba755bf..000b2d6de 100644 --- a/src/compiler/sema_liveness.c +++ b/src/compiler/sema_liveness.c @@ -175,7 +175,6 @@ static void sema_trace_stmt_liveness(Ast *ast) sema_trace_astid_liveness(ast->if_stmt.else_body); return; case AST_SWITCH_STMT: - case AST_IF_CATCH_SWITCH_STMT: sema_trace_exprid_liveness(ast->switch_stmt.cond); { FOREACH(Ast *, casestm, ast->switch_stmt.cases) sema_trace_stmt_liveness(casestm); diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index 4d57b1fb6..397462de2 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -909,7 +909,7 @@ static inline bool sema_analyse_try_unwrap(SemaContext *context, Expr *expr) static inline bool sema_analyse_try_unwrap_chain(SemaContext *context, Expr *expr, CondType cond_type, CondResult *result) { - ASSERT(cond_type == COND_TYPE_UNWRAP_BOOL || cond_type == COND_TYPE_UNWRAP); + ASSERT(cond_type == COND_TYPE_UNWRAP_BOOL); ASSERT(expr->expr_kind == EXPR_TRY_UNWRAP_CHAIN); @@ -1001,14 +1001,14 @@ static inline bool sema_analyse_last_cond(SemaContext *context, Expr *expr, Cond switch (expr->expr_kind) { case EXPR_TRY_UNWRAP_CHAIN: - if (cond_type != COND_TYPE_UNWRAP_BOOL && cond_type != COND_TYPE_UNWRAP) + if (cond_type != COND_TYPE_UNWRAP_BOOL) { SEMA_ERROR(expr, "Try unwrapping is only allowed inside of a 'while' or 'if' conditional."); return false; } return sema_analyse_try_unwrap_chain(context, expr, cond_type, result); case EXPR_CATCH_UNRESOLVED: - if (cond_type != COND_TYPE_UNWRAP_BOOL && cond_type != COND_TYPE_UNWRAP) + if (cond_type != COND_TYPE_UNWRAP_BOOL) { RETURN_SEMA_ERROR(expr, "Catch unwrapping is only allowed inside of a 'while' or 'if' conditional, maybe '@catch()' will do what you need?"); } @@ -1777,10 +1777,8 @@ static inline bool sema_analyse_if_stmt(SemaContext *context, Ast *statement) AstId else_id = statement->if_stmt.else_body; Ast *else_body = else_id ? astptr(else_id) : NULL; SCOPE_OUTER_START - CondType cond_type = then->ast_kind == AST_IF_CATCH_SWITCH_STMT - ? COND_TYPE_UNWRAP : COND_TYPE_UNWRAP_BOOL; CondResult result = COND_MISSING; - success = sema_analyse_cond(context, cond, cond_type, &result); + success = sema_analyse_cond(context, cond, COND_TYPE_UNWRAP_BOOL, &result); if (success && !ast_ok(then)) { @@ -1791,7 +1789,7 @@ static inline bool sema_analyse_if_stmt(SemaContext *context, Ast *statement) if (success && else_body) { - bool then_has_braces = then->ast_kind == AST_COMPOUND_STMT || then->ast_kind == AST_IF_CATCH_SWITCH_STMT; + bool then_has_braces = then->ast_kind == AST_COMPOUND_STMT; if (!then_has_braces) { SEMA_ERROR(then, "if-statements with an 'else' must use '{ }' even around a single statement."); @@ -1813,35 +1811,11 @@ static inline bool sema_analyse_if_stmt(SemaContext *context, Ast *statement) } } - if (then->ast_kind == AST_IF_CATCH_SWITCH_STMT) - { - Ast **cases = then->switch_stmt.cases; - if (vec_size(cases) == 1 && cases[0]->ast_kind == AST_DEFAULT_STMT) - { - if (!SEMA_WARN(cases[0], "An 'if-catch' with only a 'default' clause is unclear. " - "Removing the 'default:' will have exactly the same behaviour but will be less confusing.")) - { - return false; - } - } - DeclId label_id = statement->if_stmt.flow.label; - then->switch_stmt.flow.label = label_id; - statement->if_stmt.flow.label = 0; - Decl *label = declptrzero(label_id); - if (label) label->label.parent = astid(then); - SCOPE_START_WITH_LABEL(label_id); - success = success && sema_analyse_switch_stmt(context, then); - then_jump = context->active_scope.jump_end; - SCOPE_END; - } - else - { - SCOPE_START_WITH_LABEL(statement->if_stmt.flow.label); - if (result == COND_FALSE) context->active_scope.is_dead = true; - success = success && sema_analyse_statement(context, then); - then_jump = context->active_scope.jump_end; - SCOPE_END; - } + SCOPE_START_WITH_LABEL(statement->if_stmt.flow.label); + if (result == COND_FALSE) context->active_scope.is_dead = true; + success = success && sema_analyse_statement(context, then); + then_jump = context->active_scope.jump_end; + SCOPE_END; if (!success) goto END; else_jump = false; @@ -1986,7 +1960,7 @@ static bool sema_analyse_nextcase_stmt(SemaContext *context, Ast *statement) if (!decl_ok(target)) return false; parent = astptr(target->label.parent); AstKind kind = parent->ast_kind; - if (kind != AST_SWITCH_STMT && kind != AST_IF_CATCH_SWITCH_STMT) + if (kind != AST_SWITCH_STMT) { RETURN_SEMA_ERROR(&statement->nextcase_stmt.label, "Expected the label to match a 'switch' or 'if-catch' statement."); } @@ -2963,7 +2937,6 @@ static inline bool sema_analyse_statement_inner(SemaContext *context, Ast *state switch (statement->ast_kind) { case AST_POISONED: - case AST_IF_CATCH_SWITCH_STMT: case AST_CONTRACT: case AST_ASM_STMT: case AST_ASM_LABEL: diff --git a/test/test_suite/errors/switch_default_catch.c3 b/test/test_suite/errors/switch_default_catch.c3 deleted file mode 100644 index 81b7ac8e2..000000000 --- a/test/test_suite/errors/switch_default_catch.c3 +++ /dev/null @@ -1,10 +0,0 @@ -fn void main() -{ - int! x; - if (catch err = x) - { - default: // #warning: 'if-catch' - return; - } - return; -} \ No newline at end of file diff --git a/test/test_suite/from_docs/examples_if_catch.c3t b/test/test_suite/from_docs/examples_if_catch.c3t index 6ddf4ddc4..bdc376147 100644 --- a/test/test_suite/from_docs/examples_if_catch.c3t +++ b/test/test_suite/from_docs/examples_if_catch.c3t @@ -32,12 +32,13 @@ fn void main() // Handle the error if (catch err = ratio) { - case MathError.DIVISION_BY_ZERO: + if (err = MathError.DIVISION_BY_ZERO) + { libc::printf("Division by zero\n"); return; - default: - libc::printf("Unexpected error!"); - return; + } + libc::printf("Unexpected error!"); + return; } // Flow typing makes "ratio" // have the type double here. @@ -96,7 +97,6 @@ entry: %ratio.f = alloca i64, align 8 %retparam = alloca double, align 8 %err = alloca i64, align 8 - %switch = alloca i64, align 8 %0 = call i32 @demo.foo() %1 = call i32 @demo.bar() %2 = call i64 @demo.divide(ptr %retparam, i32 %0, i32 %1) @@ -133,31 +133,23 @@ after_check3: ; preds = %testblock end_block: ; preds = %after_check3, %assign_optional2 %6 = load i64, ptr %err, align 8 - %neq = icmp ne i64 %6, 0 - br i1 %neq, label %if.then, label %if.exit + %i2b = icmp ne i64 %6, 0 + br i1 %i2b, label %if.then, label %if.exit5 if.then: ; preds = %end_block - store i64 %6, ptr %switch, align 8 - br label %switch.entry + store i64 ptrtoint (ptr @"demo.MathError$DIVISION_BY_ZERO" to i64), ptr %err, align 8 + br i1 icmp ne (i64 ptrtoint (ptr @"demo.MathError$DIVISION_BY_ZERO" to i64), i64 0), label %if.then4, label %if.exit -switch.entry: ; preds = %if.then - %7 = load i64, ptr %switch, align 8 - %eq = icmp eq i64 ptrtoint (ptr @"demo.MathError$DIVISION_BY_ZERO" to i64), %7 - br i1 %eq, label %switch.case, label %next_if - -switch.case: ; preds = %switch.entry - %8 = call i32 (ptr, ...) @printf(ptr @.str) +if.then4: ; preds = %if.then + %7 = call i32 (ptr, ...) @printf(ptr @.str) ret void -next_if: ; preds = %switch.entry - br label %switch.default - -switch.default: ; preds = %next_if - %9 = call i32 (ptr, ...) @printf(ptr @.str.1) +if.exit: ; preds = %if.then + %8 = call i32 (ptr, ...) @printf(ptr @.str.1) ret void -if.exit: ; preds = %end_block - %10 = load double, ptr %ratio, align 8 - %11 = call i32 (ptr, ...) @printf(ptr @.str.2, double %10) +if.exit5: ; preds = %end_block + %9 = load double, ptr %ratio, align 8 + %10 = call i32 (ptr, ...) @printf(ptr @.str.2, double %9) ret void } \ No newline at end of file diff --git a/test/test_suite/statements/various_switching.c3t b/test/test_suite/statements/various_switching.c3t index 489991d3d..ad11436f3 100644 --- a/test/test_suite/statements/various_switching.c3t +++ b/test/test_suite/statements/various_switching.c3t @@ -18,15 +18,6 @@ fn void test() int! x = ByeErr.BAR?; typeid z = int.typeid; - if (catch err = x) - { - case HelloErr.FOO: - printf("Hello\n"); - case ByeErr.BAR: - printf("Bye\n"); - default: - printf("Noerrmatch\n"); - } switch (z) { case int: @@ -73,226 +64,171 @@ entry: %x = alloca i32, align 4 %x.f = alloca i64, align 8 %z = alloca i64, align 8 - %err = alloca i64, align 8 %switch = alloca i64, align 8 - %switch4 = alloca i64, align 8 %a = alloca i32, align 4 %b = alloca i32, align 4 %zy = alloca i32, align 4 - %switch27 = alloca i32, align 4 - %switch37 = alloca i8, align 1 + %switch17 = alloca i32, align 4 + %switch27 = alloca i8, align 1 store i64 ptrtoint (ptr @"mymodule.ByeErr$BAR" to i64), ptr %x.f, align 8 store i64 ptrtoint (ptr @"$ct.int" to i64), ptr %z, align 8 - br label %testblock - -testblock: ; preds = %entry - %optval = load i64, ptr %x.f, align 8 - %not_err = icmp eq i64 %optval, 0 - %0 = call i1 @llvm.expect.i1(i1 %not_err, i1 true) - br i1 %0, label %after_check, label %assign_optional - -assign_optional: ; preds = %testblock - store i64 %optval, ptr %err, align 8 - br label %end_block - -after_check: ; preds = %testblock - store i64 0, ptr %err, align 8 - br label %end_block - -end_block: ; preds = %after_check, %assign_optional - %1 = load i64, ptr %err, align 8 - %neq = icmp ne i64 %1, 0 - br i1 %neq, label %if.then, label %if.exit - -if.then: ; preds = %end_block - store i64 %1, ptr %switch, align 8 + %0 = load i64, ptr %z, align 8 + store i64 %0, ptr %switch, align 8 br label %switch.entry -switch.entry: ; preds = %if.then - %2 = load i64, ptr %switch, align 8 - %eq = icmp eq i64 ptrtoint (ptr @"mymodule.HelloErr$FOO" to i64), %2 - br i1 %eq, label %switch.case, label %next_if +switch.entry: ; preds = %entry + %1 = load i64, ptr %switch, align 8 + br label %check_subtype -switch.case: ; preds = %switch.entry +check_subtype: ; preds = %parent_type_block, %switch.entry + %2 = phi i64 [ %1, %switch.entry ], [ %typeid.parent, %parent_type_block ] + %eq = icmp eq i64 ptrtoint (ptr @"$ct.int" to i64), %2 + br i1 %eq, label %result_block, label %parent_type_block + +parent_type_block: ; preds = %check_subtype + %3 = inttoptr i64 %2 to ptr + %ptradd = getelementptr inbounds i8, ptr %3, i64 8 + %typeid.parent = load i64, ptr %ptradd, align 8 + %4 = icmp eq i64 %typeid.parent, 0 + br i1 %4, label %result_block, label %check_subtype + +result_block: ; preds = %parent_type_block, %check_subtype + %5 = phi i1 [ false, %parent_type_block ], [ true, %check_subtype ] + br i1 %5, label %switch.case, label %next_if + +switch.case: ; preds = %result_block call void (ptr, ...) @printf(ptr @.str) br label %switch.exit -next_if: ; preds = %switch.entry - %eq1 = icmp eq i64 ptrtoint (ptr @"mymodule.ByeErr$BAR" to i64), %2 - br i1 %eq1, label %switch.case2, label %next_if3 +next_if: ; preds = %result_block + br label %check_subtype1 -switch.case2: ; preds = %next_if - call void (ptr, ...) @printf(ptr @.str.3) - br label %switch.exit +check_subtype1: ; preds = %parent_type_block3, %next_if + %6 = phi i64 [ %1, %next_if ], [ %typeid.parent5, %parent_type_block3 ] + %eq2 = icmp eq i64 ptrtoint (ptr @"$ct.bool" to i64), %6 + br i1 %eq2, label %result_block6, label %parent_type_block3 -next_if3: ; preds = %next_if - br label %switch.default +parent_type_block3: ; preds = %check_subtype1 + %7 = inttoptr i64 %6 to ptr + %ptradd4 = getelementptr inbounds i8, ptr %7, i64 8 + %typeid.parent5 = load i64, ptr %ptradd4, align 8 + %8 = icmp eq i64 %typeid.parent5, 0 + br i1 %8, label %result_block6, label %check_subtype1 -switch.default: ; preds = %next_if3 - call void (ptr, ...) @printf(ptr @.str.4) - br label %switch.exit +result_block6: ; preds = %parent_type_block3, %check_subtype1 + %9 = phi i1 [ false, %parent_type_block3 ], [ true, %check_subtype1 ] + br i1 %9, label %switch.case7, label %next_if8 -switch.exit: ; preds = %switch.default, %switch.case2, %switch.case - br label %if.exit +switch.case7: ; preds = %result_block6 + br label %switch.case15 -if.exit: ; preds = %switch.exit, %end_block - %3 = load i64, ptr %z, align 8 - store i64 %3, ptr %switch4, align 8 - br label %switch.entry5 - -switch.entry5: ; preds = %if.exit - %4 = load i64, ptr %switch4, align 8 - br label %check_subtype - -check_subtype: ; preds = %parent_type_block, %switch.entry5 - %5 = phi i64 [ %4, %switch.entry5 ], [ %typeid.parent, %parent_type_block ] - %eq6 = icmp eq i64 ptrtoint (ptr @"$ct.int" to i64), %5 - br i1 %eq6, label %result_block, label %parent_type_block - -parent_type_block: ; preds = %check_subtype - %6 = inttoptr i64 %5 to ptr - %ptradd = getelementptr inbounds i8, ptr %6, i64 8 - %typeid.parent = load i64, ptr %ptradd, align 8 - %7 = icmp eq i64 %typeid.parent, 0 - br i1 %7, label %result_block, label %check_subtype - -result_block: ; preds = %parent_type_block, %check_subtype - %8 = phi i1 [ false, %parent_type_block ], [ true, %check_subtype ] - br i1 %8, label %switch.case7, label %next_if8 - -switch.case7: ; preds = %result_block - call void (ptr, ...) @printf(ptr @.str.5) - br label %switch.exit26 - -next_if8: ; preds = %result_block +next_if8: ; preds = %result_block6 br label %check_subtype9 check_subtype9: ; preds = %parent_type_block11, %next_if8 - %9 = phi i64 [ %4, %next_if8 ], [ %typeid.parent13, %parent_type_block11 ] - %eq10 = icmp eq i64 ptrtoint (ptr @"$ct.bool" to i64), %9 + %10 = phi i64 [ %1, %next_if8 ], [ %typeid.parent13, %parent_type_block11 ] + %eq10 = icmp eq i64 ptrtoint (ptr @"$ct.double" to i64), %10 br i1 %eq10, label %result_block14, label %parent_type_block11 parent_type_block11: ; preds = %check_subtype9 - %10 = inttoptr i64 %9 to ptr - %ptradd12 = getelementptr inbounds i8, ptr %10, i64 8 + %11 = inttoptr i64 %10 to ptr + %ptradd12 = getelementptr inbounds i8, ptr %11, i64 8 %typeid.parent13 = load i64, ptr %ptradd12, align 8 - %11 = icmp eq i64 %typeid.parent13, 0 - br i1 %11, label %result_block14, label %check_subtype9 + %12 = icmp eq i64 %typeid.parent13, 0 + br i1 %12, label %result_block14, label %check_subtype9 result_block14: ; preds = %parent_type_block11, %check_subtype9 - %12 = phi i1 [ false, %parent_type_block11 ], [ true, %check_subtype9 ] - br i1 %12, label %switch.case15, label %next_if16 + %13 = phi i1 [ false, %parent_type_block11 ], [ true, %check_subtype9 ] + br i1 %13, label %switch.case15, label %next_if16 -switch.case15: ; preds = %result_block14 - br label %switch.case23 +switch.case15: ; preds = %result_block14, %switch.case7 + br label %switch.default next_if16: ; preds = %result_block14 - br label %check_subtype17 + br label %switch.default -check_subtype17: ; preds = %parent_type_block19, %next_if16 - %13 = phi i64 [ %4, %next_if16 ], [ %typeid.parent21, %parent_type_block19 ] - %eq18 = icmp eq i64 ptrtoint (ptr @"$ct.double" to i64), %13 - br i1 %eq18, label %result_block22, label %parent_type_block19 +switch.default: ; preds = %next_if16, %switch.case15 + call void (ptr, ...) @printf(ptr @.str.3) + br label %switch.exit -parent_type_block19: ; preds = %check_subtype17 - %14 = inttoptr i64 %13 to ptr - %ptradd20 = getelementptr inbounds i8, ptr %14, i64 8 - %typeid.parent21 = load i64, ptr %ptradd20, align 8 - %15 = icmp eq i64 %typeid.parent21, 0 - br i1 %15, label %result_block22, label %check_subtype17 +switch.exit: ; preds = %switch.default, %switch.case + store i32 1, ptr %a, align 4 + store i32 2, ptr %b, align 4 + %14 = load i32, ptr %b, align 4 + %15 = load i32, ptr %a, align 4 + %add = add i32 %14, %15 + store i32 %add, ptr %zy, align 4 + %16 = load i32, ptr %zy, align 4 + store i32 %16, ptr %switch17, align 4 + br label %switch.entry18 -result_block22: ; preds = %parent_type_block19, %check_subtype17 - %16 = phi i1 [ false, %parent_type_block19 ], [ true, %check_subtype17 ] - br i1 %16, label %switch.case23, label %next_if24 +switch.entry18: ; preds = %switch.exit + %17 = load i32, ptr %switch17, align 4 + %18 = load i32, ptr %a, align 4 + %eq19 = icmp eq i32 %18, %17 + br i1 %eq19, label %switch.case20, label %next_if21 -switch.case23: ; preds = %result_block22, %switch.case15 +switch.case20: ; preds = %switch.entry18 + call void (ptr, ...) @printf(ptr @.str.4) + br label %switch.exit26 + +next_if21: ; preds = %switch.entry18 + %19 = load i32, ptr %b, align 4 + %eq22 = icmp eq i32 %19, %17 + br i1 %eq22, label %switch.case23, label %next_if24 + +switch.case23: ; preds = %next_if21 + call void (ptr, ...) @printf(ptr @.str.5) + br label %switch.exit26 + +next_if24: ; preds = %next_if21 br label %switch.default25 -next_if24: ; preds = %result_block22 - br label %switch.default25 - -switch.default25: ; preds = %next_if24, %switch.case23 +switch.default25: ; preds = %next_if24 call void (ptr, ...) @printf(ptr @.str.6) br label %switch.exit26 -switch.exit26: ; preds = %switch.default25, %switch.case7 - store i32 1, ptr %a, align 4 - store i32 2, ptr %b, align 4 - %17 = load i32, ptr %b, align 4 - %18 = load i32, ptr %a, align 4 - %add = add i32 %17, %18 - store i32 %add, ptr %zy, align 4 - %19 = load i32, ptr %zy, align 4 - store i32 %19, ptr %switch27, align 4 +switch.exit26: ; preds = %switch.default25, %switch.case23, %switch.case20 + store i8 1, ptr %switch27, align 1 br label %switch.entry28 switch.entry28: ; preds = %switch.exit26 - %20 = load i32, ptr %switch27, align 4 - %21 = load i32, ptr %a, align 4 - %eq29 = icmp eq i32 %21, %20 + %20 = load i8, ptr %switch27, align 1 + %21 = trunc i8 %20 to i1 + %22 = load i32, ptr %a, align 4 + %lt = icmp slt i32 %22, 0 + %eq29 = icmp eq i1 %lt, %21 br i1 %eq29, label %switch.case30, label %next_if31 switch.case30: ; preds = %switch.entry28 call void (ptr, ...) @printf(ptr @.str.7) - br label %switch.exit36 + br label %switch.exit37 next_if31: ; preds = %switch.entry28 - %22 = load i32, ptr %b, align 4 - %eq32 = icmp eq i32 %22, %20 - br i1 %eq32, label %switch.case33, label %next_if34 + %23 = load i32, ptr %a, align 4 + %eq32 = icmp eq i32 %23, 1 + %eq33 = icmp eq i1 %eq32, %21 + br i1 %eq33, label %switch.case34, label %next_if35 -switch.case33: ; preds = %next_if31 +switch.case34: ; preds = %next_if31 call void (ptr, ...) @printf(ptr @.str.8) - br label %switch.exit36 + br label %switch.exit37 -next_if34: ; preds = %next_if31 - br label %switch.default35 +next_if35: ; preds = %next_if31 + br label %switch.default36 -switch.default35: ; preds = %next_if34 +switch.default36: ; preds = %next_if35 call void (ptr, ...) @printf(ptr @.str.9) - br label %switch.exit36 + br label %switch.exit37 -switch.exit36: ; preds = %switch.default35, %switch.case33, %switch.case30 - store i8 1, ptr %switch37, align 1 - br label %switch.entry38 - -switch.entry38: ; preds = %switch.exit36 - %23 = load i8, ptr %switch37, align 1 - %24 = trunc i8 %23 to i1 - %25 = load i32, ptr %a, align 4 - %lt = icmp slt i32 %25, 0 - %eq39 = icmp eq i1 %lt, %24 - br i1 %eq39, label %switch.case40, label %next_if41 - -switch.case40: ; preds = %switch.entry38 - call void (ptr, ...) @printf(ptr @.str.10) - br label %switch.exit47 - -next_if41: ; preds = %switch.entry38 - %26 = load i32, ptr %a, align 4 - %eq42 = icmp eq i32 %26, 1 - %eq43 = icmp eq i1 %eq42, %24 - br i1 %eq43, label %switch.case44, label %next_if45 - -switch.case44: ; preds = %next_if41 - call void (ptr, ...) @printf(ptr @.str.11) - br label %switch.exit47 - -next_if45: ; preds = %next_if41 - br label %switch.default46 - -switch.default46: ; preds = %next_if45 - call void (ptr, ...) @printf(ptr @.str.12) - br label %switch.exit47 - -switch.exit47: ; preds = %switch.default46, %switch.case44, %switch.case40 +switch.exit37: ; preds = %switch.default36, %switch.case34, %switch.case30 ret void } -; Function Attrs: +; Function Attrs: nounwind uwtable define void @mymodule.main() #0 { entry: call void @mymodule.test() - call void (ptr, ...) @printf(ptr @.str.13) + call void (ptr, ...) @printf(ptr @.str.10) ret void } diff --git a/test/test_suite/switch/switch_in_defer_macro.c3t b/test/test_suite/switch/switch_in_defer_macro.c3t index 684ff5ebb..597e31a46 100644 --- a/test/test_suite/switch/switch_in_defer_macro.c3t +++ b/test/test_suite/switch/switch_in_defer_macro.c3t @@ -253,10 +253,8 @@ macro @parse_uint(self, $Type; @body(x, c, ok)) @private char! c = self.reader.read_byte(); if (catch err = c) { - case IoError.EOF: - break; - default: - return err?; + if (err = IoError.EOF) break; + return err?; } else { @@ -332,10 +330,8 @@ macro char! Lexer.read_char_for_string(&self) @private char! c = self.reader.read_byte(); if (catch err = c) { - case IoError.EOF: - return LexerError.UNTERMINATED_STRING?; - default: - return err?; + if (err == IoError.EOF) return LexerError.UNTERMINATED_STRING?; + return err?; } return c; } @@ -359,11 +355,8 @@ fn void! Lexer.parse_comment(&self, String end) @private { if (catch err = io::read_all(self.reader, buf)) { - case IoError.UNEXPECTED_EOF: - case IoError.EOF: - return LexerError.UNTERMINATED_COMMENT?; - default: - return err?; + if (err == IoError.UNEXPECTED_EOF || err == IoError.EOF) return LexerError.UNTERMINATED_COMMENT?; + return err?; } if (end == (String)buf) { @@ -400,10 +393,8 @@ fn String! Lexer.parse_ident(&self) @private char! c = self.reader.read_byte(); if (catch err = c) { - case IoError.EOF: - return str.str_view(); - default: - return err?; + if (err == IoError.EOF) return str.str_view(); + return err?; } if (!self.ident(str.len(), c)) return str.str_view(); str.append_char(c); diff --git a/test/unit/stdlib/io/scanner.c3 b/test/unit/stdlib/io/scanner.c3 index 5a6582dcc..2d4202fd8 100644 --- a/test/unit/stdlib/io/scanner.c3 +++ b/test/unit/stdlib/io/scanner.c3 @@ -28,15 +28,13 @@ fn void scanner() Results results; defer results.free(); - while LOOP: (true) + while (true) { char[]! res = sc.scan(",,"); if (catch err = res) { - case SearchResult.MISSING: - break LOOP; - default: - return err?!!; + if (err == SearchResult.MISSING) break; + return err?!!; } String str = (String)res; results.push(str.tconcat(""));