authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-03-06 21:44:27-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-03-06 21:44:27-05:00
logd96dd5bc329b69c410ef4d4def763ddb2bab13f0
treed65cf2e5689577fe4f023f6c01748af7bf330482
parent6b5cfd9d9963d2f1e91dfdb40f26c2ad11beb3c4

fix missing compile error for returning error from void async function

closes #799

3 files changed, 39 insertions(+), 29 deletions(-)

src/analyze.cpp+17-11
......@@ -464,9 +464,8 @@ TypeTableEntry *get_promise_frame_type(CodeGen *g, TypeTableEntry *return_type)
464464 TypeTableEntry *result_ptr_type = get_pointer_to_type(g, return_type, false);
465465 const char *field_names[] = {AWAITER_HANDLE_FIELD_NAME, RESULT_FIELD_NAME, RESULT_PTR_FIELD_NAME};
466466 TypeTableEntry *field_types[] = {awaiter_handle_type, return_type, result_ptr_type};
467 size_t field_count = type_has_bits(result_ptr_type) ? 3 : 1;
468467 Buf *name = buf_sprintf("AsyncFramePromise(%s)", buf_ptr(&return_type->name));
469 TypeTableEntry *entry = get_struct_type(g, buf_ptr(name), field_names, field_types, field_count);
468 TypeTableEntry *entry = get_struct_type(g, buf_ptr(name), field_names, field_types, 3);
470469
471470 return_type->promise_frame_parent = entry;
472471 return entry;
......@@ -1715,7 +1714,7 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f
17151714 buf_init_from_str(&struct_type->name, type_name);
17161715
17171716 struct_type->data.structure.src_field_count = field_count;
1718 struct_type->data.structure.gen_field_count = field_count;
1717 struct_type->data.structure.gen_field_count = 0;
17191718 struct_type->data.structure.zero_bits_known = true;
17201719 struct_type->data.structure.complete = true;
17211720 struct_type->data.structure.fields = allocate<TypeStructField>(field_count);
......@@ -1724,22 +1723,26 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f
17241723 ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(field_count);
17251724 LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count);
17261725 for (size_t i = 0; i < field_count; i += 1) {
1727 element_types[i] = field_types[i]->type_ref;
1726 element_types[struct_type->data.structure.gen_field_count] = field_types[i]->type_ref;
17281727
17291728 TypeStructField *field = &struct_type->data.structure.fields[i];
17301729 field->name = buf_create_from_str(field_names[i]);
17311730 field->type_entry = field_types[i];
17321731 field->src_index = i;
1733 field->gen_index = i;
17341732
1735 assert(type_has_bits(field->type_entry));
1733 if (type_has_bits(field->type_entry)) {
1734 field->gen_index = struct_type->data.structure.gen_field_count;
1735 struct_type->data.structure.gen_field_count += 1;
1736 } else {
1737 field->gen_index = SIZE_MAX;
1738 }
17361739
17371740 auto prev_entry = struct_type->data.structure.fields_by_name.put_unique(field->name, field);
17381741 assert(prev_entry == nullptr);
17391742 }
17401743
17411744 struct_type->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), type_name);
1742 LLVMStructSetBody(struct_type->type_ref, element_types, field_count, false);
1745 LLVMStructSetBody(struct_type->type_ref, element_types, struct_type->data.structure.gen_field_count, false);
17431746
17441747 struct_type->di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,
17451748 ZigLLVMTag_DW_structure_type(), type_name,
......@@ -1747,11 +1750,14 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f
17471750
17481751 for (size_t i = 0; i < field_count; i += 1) {
17491752 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
1753 if (type_struct_field->gen_index == SIZE_MAX) {
1754 continue;
1755 }
17501756 TypeTableEntry *field_type = type_struct_field->type_entry;
17511757 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref);
17521758 uint64_t debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, field_type->type_ref);
1753 uint64_t debug_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, struct_type->type_ref, i);
1754 di_element_types[i] = ZigLLVMCreateDebugMemberType(g->dbuilder,
1759 uint64_t debug_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, struct_type->type_ref, type_struct_field->gen_index);
1760 di_element_types[type_struct_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,
17551761 ZigLLVMTypeToScope(struct_type->di_type), buf_ptr(type_struct_field->name),
17561762 nullptr, 0,
17571763 debug_size_in_bits,
......@@ -1759,7 +1765,7 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f
17591765 debug_offset_in_bits,
17601766 0, field_type->di_type);
17611767
1762 assert(di_element_types[i]);
1768 assert(di_element_types[type_struct_field->gen_index]);
17631769 }
17641770
17651771 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, struct_type->type_ref);
......@@ -1770,7 +1776,7 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f
17701776 debug_size_in_bits,
17711777 debug_align_in_bits,
17721778 0,
1773 nullptr, di_element_types, field_count, 0, nullptr, "");
1779 nullptr, di_element_types, struct_type->data.structure.gen_field_count, 0, nullptr, "");
17741780
17751781 ZigLLVMReplaceTemporary(g->dbuilder, struct_type->di_type, replacement_di_type);
17761782 struct_type->di_type = replacement_di_type;
src/ir.cpp+11-18
......@@ -948,12 +948,10 @@ static IrInstruction *ir_build_const_promise_init(IrBuilder *irb, Scope *scope,
948948 const_instruction->base.value.data.x_struct.fields[0].type = struct_type->data.structure.fields[0].type_entry;
949949 const_instruction->base.value.data.x_struct.fields[0].special = ConstValSpecialStatic;
950950 const_instruction->base.value.data.x_struct.fields[0].data.x_maybe = nullptr;
951 if (struct_type->data.structure.src_field_count > 1) {
952 const_instruction->base.value.data.x_struct.fields[1].type = return_type;
953 const_instruction->base.value.data.x_struct.fields[1].special = ConstValSpecialUndef;
954 const_instruction->base.value.data.x_struct.fields[2].type = struct_type->data.structure.fields[2].type_entry;
955 const_instruction->base.value.data.x_struct.fields[2].special = ConstValSpecialUndef;
956 }
951 const_instruction->base.value.data.x_struct.fields[1].type = return_type;
952 const_instruction->base.value.data.x_struct.fields[1].special = ConstValSpecialUndef;
953 const_instruction->base.value.data.x_struct.fields[2].type = struct_type->data.structure.fields[2].type_entry;
954 const_instruction->base.value.data.x_struct.fields[2].special = ConstValSpecialUndef;
957955 return &const_instruction->base;
958956}
959957
......@@ -2741,10 +2739,8 @@ static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode
27412739 return return_inst;
27422740 }
27432741
2744 if (irb->exec->coro_result_ptr_field_ptr) {
2745 IrInstruction *result_ptr = ir_build_load_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr);
2746 ir_build_store_ptr(irb, scope, node, result_ptr, return_value);
2747 }
2742 IrInstruction *result_ptr = ir_build_load_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr);
2743 ir_build_store_ptr(irb, scope, node, result_ptr, return_value);
27482744 IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node,
27492745 get_maybe_type(irb->codegen, irb->codegen->builtin_types.entry_promise));
27502746 // TODO replace replacement_value with @intToPtr(?promise, 0x1) when it doesn't crash zig
......@@ -6328,14 +6324,11 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
63286324 Buf *awaiter_handle_field_name = buf_create_from_str(AWAITER_HANDLE_FIELD_NAME);
63296325 irb->exec->coro_awaiter_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,
63306326 awaiter_handle_field_name);
6331 if (type_has_bits(return_type)) {
6332 Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME);
6333 coro_result_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name);
6334 result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME);
6335 irb->exec->coro_result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,
6336 result_ptr_field_name);
6337 ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr, coro_result_field_ptr);
6338 }
6327 Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME);
6328 coro_result_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name);
6329 result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME);
6330 irb->exec->coro_result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name);
6331 ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr, coro_result_field_ptr);
63396332
63406333
63416334 irb->exec->coro_early_final = ir_create_basic_block(irb, scope, "CoroEarlyFinal");
test/compile_errors.zig+11
......@@ -1,6 +1,17 @@
11const tests = @import("tests.zig");
22
33pub fn addCases(cases: &tests.CompileErrorContext) void {
4 cases.add("returning error from void async function",
5 \\const std = @import("std");
6 \\export fn entry() void {
7 \\ const p = async(std.debug.global_allocator) amain() catch unreachable;
8 \\}
9 \\async fn amain() void {
10 \\ return error.ShouldBeCompileError;
11 \\}
12 ,
13 ".tmp_source.zig:6:17: error: expected type 'void', found 'error{ShouldBeCompileError}'");
14
415 cases.add("var not allowed in structs",
516 \\export fn entry() void {
617 \\ var s = (struct{v: var}){.v=i32(10)};