Skip to content

Commit

Permalink
copy elision: implicit cast error set to error union runtime
Browse files Browse the repository at this point in the history
```zig
export fn entry() void {
    var x = error.Failure;
    var y: error!Foo = x;
}
```

```llvm
define void @entry() #2 !dbg !42 {
Entry:
  %x = alloca i16, align 2
  %y = alloca { i16, %Foo }, align 4
  store i16 1, i16* %x, align 2, !dbg !63
  call void @llvm.dbg.declare(metadata i16* %x, metadata !46, metadata !DIExpression()), !dbg !64
  %0 = load i16, i16* %x, align 2, !dbg !65
  %1 = getelementptr inbounds { i16, %Foo }, { i16, %Foo }* %y, i32 0, i32 0, !dbg !66
  store i16 %0, i16* %1, align 2, !dbg !65
  call void @llvm.dbg.declare(metadata { i16, %Foo }* %y, metadata !48, metadata !DIExpression()), !dbg !66
  ret void, !dbg !67
}
```
  • Loading branch information
andrewrk committed Oct 30, 2018
1 parent 88427ae commit 7d6c967
Showing 1 changed file with 11 additions and 16 deletions.
27 changes: 11 additions & 16 deletions src/ir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13377,30 +13377,25 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction,
}

static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr,
IrInstruction *ptr, IrInstruction *value)
IrInstruction *uncasted_ptr, IrInstruction *value)
{
if (ptr->value.type->id != ZigTypeIdPointer) {
ir_add_error(ira, ptr,
buf_sprintf("attempt to dereference non pointer type '%s'", buf_ptr(&ptr->value.type->name)));
if (uncasted_ptr->value.type->id != ZigTypeIdPointer) {
ir_add_error(ira, uncasted_ptr,
buf_sprintf("attempt to dereference non pointer type '%s'", buf_ptr(&uncasted_ptr->value.type->name)));
return ira->codegen->invalid_instruction;
}

Error err;
if ((err = resolve_possible_alloca_inference(ira, ptr, value->value.type)))
return ira->codegen->invalid_instruction;

if (ptr->value.data.x_ptr.special == ConstPtrSpecialDiscard) {
if (uncasted_ptr->value.data.x_ptr.special == ConstPtrSpecialDiscard) {
return ir_const_void(ira, source_instr);
}

if (ptr->value.type->data.pointer.is_const && !source_instr->is_gen) {
if (uncasted_ptr->value.type->data.pointer.is_const && !source_instr->is_gen) {
ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant"));
return ira->codegen->invalid_instruction;
}

ZigType *child_type = ptr->value.type->data.pointer.child_type;
IrInstruction *casted_value = ir_implicit_cast(ira, value, child_type);
if (casted_value == ira->codegen->invalid_instruction)
IrInstruction *ptr = ir_implicit_cast_result(ira, uncasted_ptr, value->value.type);
if (type_is_invalid(ptr->value.type))
return ira->codegen->invalid_instruction;

if (instr_is_comptime(ptr) && ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
Expand All @@ -13409,12 +13404,12 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
return ira->codegen->invalid_instruction;
}
if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) {
if (instr_is_comptime(casted_value)) {
if (instr_is_comptime(value)) {
ConstExprValue *dest_val = ir_const_ptr_pointee(ira, &ptr->value, source_instr->source_node);
if (dest_val == nullptr)
return ira->codegen->invalid_instruction;
if (dest_val->special != ConstValSpecialRuntime) {
*dest_val = casted_value->value;
*dest_val = value->value;
if (!ira->new_irb.current_basic_block->must_be_comptime_source_instr) {
ira->new_irb.current_basic_block->must_be_comptime_source_instr = source_instr;
}
Expand All @@ -13431,7 +13426,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
}

IrInstruction *result = ir_build_store_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node,
ptr, casted_value);
ptr, value);
result->value.type = ira->codegen->builtin_types.entry_void;
return result;
}
Expand Down

0 comments on commit 7d6c967

Please sign in to comment.