Skip to content

Commit 952da3c

Browse files
committed
copy elision: catch unreachable with identifier expr
```zig export fn entry() void { var x: error!Bar = fail(); var z = x catch unreachable; } ``` ```llvm define void @entry() #2 !dbg !42 { Entry: %error_return_trace_addresses = alloca [30 x i64], align 8 %error_return_trace = alloca %StackTrace, align 8 %x = alloca { i16, %Bar }, align 4 %z = alloca %Bar, align 4 %0 = getelementptr inbounds %StackTrace, %StackTrace* %error_return_trace, i32 0, i32 0 store i64 0, i64* %0, align 8 %1 = getelementptr inbounds %StackTrace, %StackTrace* %error_return_trace, i32 0, i32 1 %2 = getelementptr inbounds %"[]usize", %"[]usize"* %1, i32 0, i32 0 %3 = getelementptr inbounds [30 x i64], [30 x i64]* %error_return_trace_addresses, i64 0, i64 0 store i64* %3, i64** %2, align 8 %4 = getelementptr inbounds %"[]usize", %"[]usize"* %1, i32 0, i32 1 store i64 30, i64* %4, align 8 %5 = getelementptr inbounds { i16, %Bar }, { i16, %Bar }* %x, i32 0, i32 0, !dbg !59 %6 = call fastcc i16 @fail(%StackTrace* %error_return_trace), !dbg !60 store i16 %6, i16* %5, align 2, !dbg !60 call void @llvm.dbg.declare(metadata { i16, %Bar }* %x, metadata !46, metadata !DIExpression()), !dbg !59 %7 = getelementptr inbounds { i16, %Bar }, { i16, %Bar }* %x, i32 0, i32 1, !dbg !61 %8 = bitcast %Bar* %7 to i8*, !dbg !61 %9 = bitcast %Bar* %z to i8*, !dbg !61 call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %9, i8* align 4 %8, i64 8, i1 false), !dbg !61 %10 = getelementptr inbounds { i16, %Bar }, { i16, %Bar }* %x, i32 0, i32 0, !dbg !61 %11 = load i16, i16* %10, align 2, !dbg !61 %12 = icmp eq i16 %11, 0, !dbg !62 br i1 %12, label %UnwrapErrOk, label %UnwrapErrError, !dbg !62 UnwrapErrError: ; preds = %Entry tail call fastcc void @__zig_fail_unwrap(%StackTrace* %error_return_trace, i16 %11), !dbg !62 unreachable, !dbg !62 UnwrapErrOk: ; preds = %Entry call void @llvm.dbg.declare(metadata %Bar* %z, metadata !57, metadata !DIExpression()), !dbg !63 ret void, !dbg !64 } ```
1 parent 5ee4e5a commit 952da3c

File tree

1 file changed

+24
-4
lines changed

1 file changed

+24
-4
lines changed

src/ir.cpp

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3138,6 +3138,29 @@ static IrInstruction *ir_gen_value(IrBuilder *irb, Scope *scope, AstNode *node,
31383138
return ir_lval_wrap(irb, scope, value, lval);
31393139
}
31403140

3141+
static IrInstruction *ir_gen_ptr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval,
3142+
IrInstruction *result_loc, IrInstruction *ptr)
3143+
{
3144+
switch (lval) {
3145+
case LValPtr:
3146+
assert(result_loc == nullptr);
3147+
return ptr;
3148+
case LValNone:
3149+
return ir_build_load_ptr(irb, scope, node, ptr, result_loc);
3150+
case LValErrorUnion: {
3151+
// ptr points to an error union;
3152+
// result_loc points to the result payload
3153+
// must return the error code
3154+
IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, scope, node, ptr, false);
3155+
ir_build_load_ptr(irb, scope, node, payload_ptr, result_loc);
3156+
return ir_build_unwrap_err_code(irb, scope, node, ptr);
3157+
}
3158+
case LValOptional:
3159+
zig_panic("TODO");
3160+
}
3161+
zig_unreachable();
3162+
}
3163+
31413164
static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval,
31423165
IrInstruction *result_loc)
31433166
{
@@ -3735,10 +3758,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
37353758
ZigVar *var = find_variable(irb->codegen, scope, variable_name, &crossed_fndef_scope);
37363759
if (var) {
37373760
IrInstruction *var_ptr = ir_build_var_ptr_x(irb, scope, node, var, crossed_fndef_scope);
3738-
if (lval == LValPtr)
3739-
return var_ptr;
3740-
IrInstruction *loaded = ir_build_load_ptr(irb, scope, node, var_ptr, result_loc);
3741-
return ir_lval_wrap(irb, scope, loaded, lval);
3761+
return ir_gen_ptr(irb, scope, node, lval, result_loc, var_ptr);
37423762
}
37433763

37443764
Tld *tld = find_decl(irb->codegen, scope, variable_name);

0 commit comments

Comments
 (0)