diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index 13f4fc91f..1e7290b04 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -4687,6 +4687,17 @@ BEValue llvm_emit_assign_expr(GenContext *c, BEValue *ref, Expr *expr, LLVMValue { if (IS_FAILABLE(expr)) { + if (expr->expr_kind == EXPR_FAILABLE) + { + c->error_var = NULL; + c->catch_block = NULL; + BEValue result; + llvm_emit_expr(c, &result, expr->inner_expr); + llvm_store_bevalue_dest_aligned(c, failable, &result); + llvm_value_set(&result, LLVMGetUndef(llvm_get_type(c, ref->type)), ref->type); + POP_ERROR(); + return result; + } assign_block = llvm_basic_block_new(c, "after_assign"); c->error_var = failable; c->catch_block = assign_block; diff --git a/test/test_suite/errors/failable_inits.c3t b/test/test_suite/errors/failable_inits.c3t index fafa6eda6..e9bfdc157 100644 --- a/test/test_suite/errors/failable_inits.c3t +++ b/test/test_suite/errors/failable_inits.c3t @@ -38,18 +38,15 @@ entry: %y = alloca %Bar, align 4 %error_var = alloca i64, align 8 store i64 ptrtoint ([2 x i8*]* @"test.Foo$elements" to i64), i64* %x.f, align 8 - br label %after_assign - -after_assign: ; preds = %entry %0 = load i64, i64* %x.f, align 8 %not_err = icmp eq i64 %0, 0 br i1 %not_err, label %after_check, label %error -error: ; preds = %after_assign +error: ; preds = %entry store i64 %0, i64* %error_var, align 8 br label %guard_block -after_check: ; preds = %after_assign +after_check: ; preds = %entry br label %noerr_block guard_block: ; preds = %error @@ -115,3 +112,6 @@ after.errcheck2: ; preds = %voiderr voiderr3: ; preds = %after.errcheck2, %voiderr ret void } + +; Function Attrs: argmemonly nofree nounwind willreturn +declare void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i32, i1 immarg) #1 diff --git a/test/test_suite/errors/failable_taddr_and_access.c3t b/test/test_suite/errors/failable_taddr_and_access.c3t index 7a17f92d7..dd6920e26 100644 --- a/test/test_suite/errors/failable_taddr_and_access.c3t +++ b/test/test_suite/errors/failable_taddr_and_access.c3t @@ -44,7 +44,7 @@ entry: %w = alloca %Foo*, align 8 %w.f = alloca i64, align 8 %literal = alloca %Foo, align 4 - %literal5 = alloca %Foo, align 4 + %literal4 = alloca %Foo, align 4 store i32 2, i32* %z, align 4 store i64 0, i64* %z.f, align 8 %0 = getelementptr inbounds %Foo, %Foo* %literal, i32 0, i32 0 @@ -79,45 +79,42 @@ after_check2: ; preds = %after_assign voiderr: ; preds = %after_check2, %after_assign store i64 ptrtoint ([1 x i8*]* @"test.MyErr$elements" to i64), i64* %z.f, align 8 - br label %after_assign3 + br label %voiderr3 -after_assign3: ; preds = %voiderr - br label %voiderr4 - -voiderr4: ; preds = %after_assign3 - %9 = getelementptr inbounds %Foo, %Foo* %literal5, i32 0, i32 0 +voiderr3: ; preds = %voiderr + %9 = getelementptr inbounds %Foo, %Foo* %literal4, i32 0, i32 0 %10 = load i64, i64* %z.f, align 8 - %not_err6 = icmp eq i64 %10, 0 - br i1 %not_err6, label %after_check8, label %error7 + %not_err5 = icmp eq i64 %10, 0 + br i1 %not_err5, label %after_check7, label %error6 -error7: ; preds = %voiderr4 +error6: ; preds = %voiderr3 store i64 %10, i64* %w.f, align 8 - br label %after_assign9 + br label %after_assign8 -after_check8: ; preds = %voiderr4 +after_check7: ; preds = %voiderr3 %11 = load i32, i32* %z, align 4 store i32 %11, i32* %9, align 4 - %12 = getelementptr inbounds %Foo, %Foo* %literal5, i32 0, i32 1 + %12 = getelementptr inbounds %Foo, %Foo* %literal4, i32 0, i32 1 store i32 0, i32* %12, align 4 - store %Foo* %literal5, %Foo** %w, align 8 + store %Foo* %literal4, %Foo** %w, align 8 store i64 0, i64* %w.f, align 8 - br label %after_assign9 + br label %after_assign8 -after_assign9: ; preds = %after_check8, %error7 - br label %voiderr10 +after_assign8: ; preds = %after_check7, %error6 + br label %voiderr9 -voiderr10: ; preds = %after_assign9 +voiderr9: ; preds = %after_assign8 %13 = load i64, i64* %w.f, align 8 - %not_err11 = icmp eq i64 %13, 0 - br i1 %not_err11, label %after_check12, label %voiderr13 + %not_err10 = icmp eq i64 %13, 0 + br i1 %not_err10, label %after_check11, label %voiderr12 -after_check12: ; preds = %voiderr10 +after_check11: ; preds = %voiderr9 %14 = load %Foo*, %Foo** %w, align 8 %15 = getelementptr inbounds %Foo, %Foo* %14, i32 0, i32 0 %16 = load i32, i32* %15, align 8 %17 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i32 0, i32 0), i32 %16) - br label %voiderr13 + br label %voiderr12 -voiderr13: ; preds = %after_check12, %voiderr10 +voiderr12: ; preds = %after_check11, %voiderr9 ret void } \ No newline at end of file diff --git a/test/test_suite/errors/simple_static_failable.c3t b/test/test_suite/errors/simple_static_failable.c3t index 39f46d786..373ce2e0d 100644 --- a/test/test_suite/errors/simple_static_failable.c3t +++ b/test/test_suite/errors/simple_static_failable.c3t @@ -20,8 +20,5 @@ entry: %i = alloca i32, align 4 %i.f = alloca i64, align 8 store i64 ptrtoint ([1 x i8*]* @"foo.Blurg$elements" to i64), i64* %i.f, align 8 - br label %after_assign - -after_assign: ; preds = %entry 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 0db2515b2..83f30c57f 100644 --- a/test/test_suite/statements/various_switching.c3t +++ b/test/test_suite/statements/various_switching.c3t @@ -71,13 +71,10 @@ entry: %zy = alloca i32, align 4 %switch17 = alloca i32, align 4 store i64 ptrtoint ([2 x i8*]* @"mymodule.ByeErr$elements" to i64), i64* %x.f, align 8 - br label %after_assign - -after_assign: ; preds = %entry store i64 5, i64* %z, align 8 br label %testblock -testblock: ; preds = %after_assign +testblock: ; preds = %entry %0 = load i64, i64* %x.f, align 8 %not_err = icmp eq i64 %0, 0 br i1 %not_err, label %after_check, label %error