Files
c3c/test/test_suite/from_docs/examples_if_catch.c3t
Christoffer Lerno cdabe8fd9e - Create optional with ~ instead of ?. return io::EOF?; becomes return io::EOF~.
- Deprecated use of `?` to create optional.
2026-01-20 16:10:28 +01:00

153 lines
4.3 KiB
Plaintext

// #target: macos-x64
module demo;
import libc;
import std::io;
faultdef DIVISION_BY_ZERO;
fn int foo() { return 123; }
fn int bar() { return 0; }
fn double? divide(int a, int b)
{
if (b == 0) return DIVISION_BY_ZERO~;
return (double)(a) / (double)(b);
}
// Rethrowing an error uses "?" suffix
fn void? testMayError()
{
divide(foo(), bar())!;
}
fn void main()
{
// ratio has an optional type.
double? ratio = divide(foo(), bar());
// Handle the error
if (catch err = ratio)
{
if (err == DIVISION_BY_ZERO)
{
libc::printf("Division by zero\n");
return;
}
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.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
%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
%3 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
br i1 %3, 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
%4 = load i64, ptr %error_var, align 8
ret i64 %4
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
%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
%3 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
br i1 %3, 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
%4 = load double, ptr %retparam, align 8
store double %4, 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
%5 = call i1 @llvm.expect.i1(i1 %not_err1, i1 true)
br i1 %5, 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
%6 = load i64, ptr %err, align 8
%i2b = icmp ne i64 %6, 0
br i1 %i2b, label %if.then, label %if.exit5
if.then: ; preds = %end_block
%7 = load i64, ptr %err, align 8
%eq = icmp eq i64 %7, ptrtoint (ptr @demo.DIVISION_BY_ZERO to i64)
br i1 %eq, label %if.then4, label %if.exit
if.then4: ; preds = %if.then
%8 = call i32 (ptr, ...) @printf(ptr @.str)
ret void
if.exit: ; preds = %if.then
%9 = call i32 (ptr, ...) @printf(ptr @.str.1)
ret void
if.exit5: ; preds = %end_block
%10 = load double, ptr %ratio, align 8
%11 = call i32 (ptr, ...) @printf(ptr @.str.2, double %10)
ret void
}