Files
c3c/test/test_suite2/from_docs/examples_if_catch.c3t
Christoffer Lerno 44df6eb75b Cleanup.
2022-08-12 18:13:24 +02:00

160 lines
4.6 KiB
C

// #target: macos-x64
module demo;
import libc;
import std::io;
fault MathError
{
DIVISION_BY_ZERO
}
fn int foo() { return 123; }
fn int bar() { return 0; }
fn double! divide(int a, int b)
{
if (b == 0) return MathError.DIVISION_BY_ZERO!;
return (double)(a) / (double)(b);
}
// Rethrowing an error uses "?" suffix
fn void! testMayError()
{
divide(foo(), bar())?;
}
fn void main()
{
// ratio has a failable type.
double! ratio = divide(foo(), bar());
// Handle the error
if (catch err = ratio)
{
case MathError.DIVISION_BY_ZERO:
libc::printf("Division by zero\n");
return;
default:
libc::printf("Unexpected error!");
return;
}
// Flow typing makes "ratio"
// have the type double here.
libc::printf("Ratio was %f\n", ratio);
}
/* #expect: demo.ll
define i64 @demo_divide(ptr %0, i32 %1, i32 %2) #0 {
entry:
%reterr = alloca i64, align 8
%eq = icmp eq i32 %2, 0
br i1 %eq, label %if.then, label %if.exit
if.then: ; preds = %entry
ret i64 ptrtoint (ptr @"demo_MathError$DIVISION_BY_ZERO" to i64)
if.exit: ; preds = %entry
%sifp = sitofp i32 %1 to double
%sifp1 = sitofp i32 %2 to double
%fdiv = fdiv double %sifp, %sifp1
store double %fdiv, ptr %0, align 8
ret i64 0
}
define i64 @demo_testMayError() #0 {
entry:
%error_var = alloca i64, align 8
%retparam = alloca double, align 8
%reterr = 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)
%not_err = icmp eq i64 %2, 0
br i1 %not_err, label %after_check, label %assign_optional
assign_optional: ; preds = %entry
store i64 %2, ptr %error_var, align 8
br label %guard_block
after_check: ; preds = %entry
br label %noerr_block
guard_block: ; preds = %assign_optional
%3 = load i64, ptr %error_var, align 8
ret i64 %3
noerr_block: ; preds = %after_check
ret i64 0
}
define void @demo_main() #0 {
entry:
%ratio = alloca double, align 8
%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)
%not_err = icmp eq i64 %2, 0
br i1 %not_err, label %after_check, label %assign_optional
assign_optional: ; preds = %entry
store i64 %2, ptr %ratio.f, align 8
br label %after_assign
after_check: ; preds = %entry
%3 = load double, ptr %retparam, align 8
store double %3, ptr %ratio, align 8
store i64 0, ptr %ratio.f, align 8
br label %after_assign
after_assign: ; preds = %after_check, %assign_optional
br label %testblock
testblock: ; preds = %after_assign
%optval = load i64, ptr %ratio.f, align 8
%not_err1 = icmp eq i64 %optval, 0
br i1 %not_err1, label %after_check3, label %assign_optional2
assign_optional2: ; preds = %testblock
store i64 %optval, ptr %err, align 8
br label %end_block
after_check3: ; preds = %testblock
store i64 0, ptr %err, align 8
br label %end_block
end_block: ; preds = %after_check3, %assign_optional2
%4 = load i64, ptr %err, align 8
%neq = icmp ne i64 %4, 0
br i1 %neq, label %if.then, label %if.exit
if.then: ; preds = %end_block
store i64 %4, ptr %switch, align 8
br label %switch.entry
switch.entry: ; preds = %if.then
%5 = load i64, ptr %switch, align 8
%eq = icmp eq i64 ptrtoint (ptr @"demo_MathError$DIVISION_BY_ZERO" to i64), %5
br i1 %eq, label %switch.case, label %next_if
switch.case: ; preds = %switch.entry
%6 = call i32 (ptr, ...) @printf(ptr @.str)
ret void
next_if: ; preds = %switch.entry
br label %switch.default
switch.default: ; preds = %next_if
%7 = call i32 (ptr, ...) @printf(ptr @.str.1)
ret void
if.exit: ; preds = %end_block
%8 = load double, ptr %ratio, align 8
%9 = call i32 (ptr, ...) @printf(ptr @.str.2, double %8)
ret void
}