Skip to content

Commit

Permalink
fix missing compile error for returning error from void async function
Browse files Browse the repository at this point in the history
closes #799
  • Loading branch information
andrewrk committed Mar 7, 2018
1 parent 6b5cfd9 commit d96dd5b
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 29 deletions.
28 changes: 17 additions & 11 deletions src/analyze.cpp
Expand Up @@ -464,9 +464,8 @@ TypeTableEntry *get_promise_frame_type(CodeGen *g, TypeTableEntry *return_type)
TypeTableEntry *result_ptr_type = get_pointer_to_type(g, return_type, false);
const char *field_names[] = {AWAITER_HANDLE_FIELD_NAME, RESULT_FIELD_NAME, RESULT_PTR_FIELD_NAME};
TypeTableEntry *field_types[] = {awaiter_handle_type, return_type, result_ptr_type};
size_t field_count = type_has_bits(result_ptr_type) ? 3 : 1;
Buf *name = buf_sprintf("AsyncFramePromise(%s)", buf_ptr(&return_type->name));
TypeTableEntry *entry = get_struct_type(g, buf_ptr(name), field_names, field_types, field_count);
TypeTableEntry *entry = get_struct_type(g, buf_ptr(name), field_names, field_types, 3);

return_type->promise_frame_parent = entry;
return entry;
Expand Down Expand Up @@ -1715,7 +1714,7 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f
buf_init_from_str(&struct_type->name, type_name);

struct_type->data.structure.src_field_count = field_count;
struct_type->data.structure.gen_field_count = field_count;
struct_type->data.structure.gen_field_count = 0;
struct_type->data.structure.zero_bits_known = true;
struct_type->data.structure.complete = true;
struct_type->data.structure.fields = allocate<TypeStructField>(field_count);
Expand All @@ -1724,42 +1723,49 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f
ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(field_count);
LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count);
for (size_t i = 0; i < field_count; i += 1) {
element_types[i] = field_types[i]->type_ref;
element_types[struct_type->data.structure.gen_field_count] = field_types[i]->type_ref;

TypeStructField *field = &struct_type->data.structure.fields[i];
field->name = buf_create_from_str(field_names[i]);
field->type_entry = field_types[i];
field->src_index = i;
field->gen_index = i;

assert(type_has_bits(field->type_entry));
if (type_has_bits(field->type_entry)) {
field->gen_index = struct_type->data.structure.gen_field_count;
struct_type->data.structure.gen_field_count += 1;
} else {
field->gen_index = SIZE_MAX;
}

auto prev_entry = struct_type->data.structure.fields_by_name.put_unique(field->name, field);
assert(prev_entry == nullptr);
}

struct_type->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), type_name);
LLVMStructSetBody(struct_type->type_ref, element_types, field_count, false);
LLVMStructSetBody(struct_type->type_ref, element_types, struct_type->data.structure.gen_field_count, false);

struct_type->di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,
ZigLLVMTag_DW_structure_type(), type_name,
ZigLLVMCompileUnitToScope(g->compile_unit), nullptr, 0);

for (size_t i = 0; i < field_count; i += 1) {
TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
if (type_struct_field->gen_index == SIZE_MAX) {
continue;
}
TypeTableEntry *field_type = type_struct_field->type_entry;
uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref);
uint64_t debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, field_type->type_ref);
uint64_t debug_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, struct_type->type_ref, i);
di_element_types[i] = ZigLLVMCreateDebugMemberType(g->dbuilder,
uint64_t debug_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, struct_type->type_ref, type_struct_field->gen_index);
di_element_types[type_struct_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,
ZigLLVMTypeToScope(struct_type->di_type), buf_ptr(type_struct_field->name),
nullptr, 0,
debug_size_in_bits,
debug_align_in_bits,
debug_offset_in_bits,
0, field_type->di_type);

assert(di_element_types[i]);
assert(di_element_types[type_struct_field->gen_index]);
}

uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, struct_type->type_ref);
Expand All @@ -1770,7 +1776,7 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f
debug_size_in_bits,
debug_align_in_bits,
0,
nullptr, di_element_types, field_count, 0, nullptr, "");
nullptr, di_element_types, struct_type->data.structure.gen_field_count, 0, nullptr, "");

ZigLLVMReplaceTemporary(g->dbuilder, struct_type->di_type, replacement_di_type);
struct_type->di_type = replacement_di_type;
Expand Down
29 changes: 11 additions & 18 deletions src/ir.cpp
Expand Up @@ -948,12 +948,10 @@ static IrInstruction *ir_build_const_promise_init(IrBuilder *irb, Scope *scope,
const_instruction->base.value.data.x_struct.fields[0].type = struct_type->data.structure.fields[0].type_entry;
const_instruction->base.value.data.x_struct.fields[0].special = ConstValSpecialStatic;
const_instruction->base.value.data.x_struct.fields[0].data.x_maybe = nullptr;
if (struct_type->data.structure.src_field_count > 1) {
const_instruction->base.value.data.x_struct.fields[1].type = return_type;
const_instruction->base.value.data.x_struct.fields[1].special = ConstValSpecialUndef;
const_instruction->base.value.data.x_struct.fields[2].type = struct_type->data.structure.fields[2].type_entry;
const_instruction->base.value.data.x_struct.fields[2].special = ConstValSpecialUndef;
}
const_instruction->base.value.data.x_struct.fields[1].type = return_type;
const_instruction->base.value.data.x_struct.fields[1].special = ConstValSpecialUndef;
const_instruction->base.value.data.x_struct.fields[2].type = struct_type->data.structure.fields[2].type_entry;
const_instruction->base.value.data.x_struct.fields[2].special = ConstValSpecialUndef;
return &const_instruction->base;
}

Expand Down Expand Up @@ -2741,10 +2739,8 @@ static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode
return return_inst;
}

if (irb->exec->coro_result_ptr_field_ptr) {
IrInstruction *result_ptr = ir_build_load_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr);
ir_build_store_ptr(irb, scope, node, result_ptr, return_value);
}
IrInstruction *result_ptr = ir_build_load_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr);
ir_build_store_ptr(irb, scope, node, result_ptr, return_value);
IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node,
get_maybe_type(irb->codegen, irb->codegen->builtin_types.entry_promise));
// TODO replace replacement_value with @intToPtr(?promise, 0x1) when it doesn't crash zig
Expand Down Expand Up @@ -6328,14 +6324,11 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
Buf *awaiter_handle_field_name = buf_create_from_str(AWAITER_HANDLE_FIELD_NAME);
irb->exec->coro_awaiter_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,
awaiter_handle_field_name);
if (type_has_bits(return_type)) {
Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME);
coro_result_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name);
result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME);
irb->exec->coro_result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,
result_ptr_field_name);
ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr, coro_result_field_ptr);
}
Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME);
coro_result_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name);
result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME);
irb->exec->coro_result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name);
ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr, coro_result_field_ptr);


irb->exec->coro_early_final = ir_create_basic_block(irb, scope, "CoroEarlyFinal");
Expand Down
11 changes: 11 additions & 0 deletions test/compile_errors.zig
@@ -1,6 +1,17 @@
const tests = @import("tests.zig");

pub fn addCases(cases: &tests.CompileErrorContext) void {
cases.add("returning error from void async function",
\\const std = @import("std");
\\export fn entry() void {
\\ const p = async(std.debug.global_allocator) amain() catch unreachable;
\\}
\\async fn amain() void {
\\ return error.ShouldBeCompileError;
\\}
,
".tmp_source.zig:6:17: error: expected type 'void', found 'error{ShouldBeCompileError}'");

cases.add("var not allowed in structs",
\\export fn entry() void {
\\ var s = (struct{v: var}){.v=i32(10)};
Expand Down

0 comments on commit d96dd5b

Please sign in to comment.