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)...@@ -464,9 +464,8 @@ TypeTableEntry *get_promise_frame_type(CodeGen *g, TypeTableEntry *return_type)
464 TypeTableEntry *result_ptr_type = get_pointer_to_type(g, return_type, false);464 TypeTableEntry *result_ptr_type = get_pointer_to_type(g, return_type, false);
465 const char *field_names[] = {AWAITER_HANDLE_FIELD_NAME, RESULT_FIELD_NAME, RESULT_PTR_FIELD_NAME};465 const char *field_names[] = {AWAITER_HANDLE_FIELD_NAME, RESULT_FIELD_NAME, RESULT_PTR_FIELD_NAME};
466 TypeTableEntry *field_types[] = {awaiter_handle_type, return_type, result_ptr_type};466 TypeTableEntry *field_types[] = {awaiter_handle_type, return_type, result_ptr_type};
467 size_t field_count = type_has_bits(result_ptr_type) ? 3 : 1;
468 Buf *name = buf_sprintf("AsyncFramePromise(%s)", buf_ptr(&return_type->name));467 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
471 return_type->promise_frame_parent = entry;470 return_type->promise_frame_parent = entry;
472 return entry;471 return entry;
...@@ -1715,7 +1714,7 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f...@@ -1715,7 +1714,7 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f
1715 buf_init_from_str(&struct_type->name, type_name);1714 buf_init_from_str(&struct_type->name, type_name);
17161715
1717 struct_type->data.structure.src_field_count = field_count;1716 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;
1719 struct_type->data.structure.zero_bits_known = true;1718 struct_type->data.structure.zero_bits_known = true;
1720 struct_type->data.structure.complete = true;1719 struct_type->data.structure.complete = true;
1721 struct_type->data.structure.fields = allocate<TypeStructField>(field_count);1720 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...@@ -1724,22 +1723,26 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f
1724 ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(field_count);1723 ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(field_count);
1725 LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count);1724 LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count);
1726 for (size_t i = 0; i < field_count; i += 1) {1725 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
1729 TypeStructField *field = &struct_type->data.structure.fields[i];1728 TypeStructField *field = &struct_type->data.structure.fields[i];
1730 field->name = buf_create_from_str(field_names[i]);1729 field->name = buf_create_from_str(field_names[i]);
1731 field->type_entry = field_types[i];1730 field->type_entry = field_types[i];
1732 field->src_index = i;1731 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
1737 auto prev_entry = struct_type->data.structure.fields_by_name.put_unique(field->name, field);1740 auto prev_entry = struct_type->data.structure.fields_by_name.put_unique(field->name, field);
1738 assert(prev_entry == nullptr);1741 assert(prev_entry == nullptr);
1739 }1742 }
17401743
1741 struct_type->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), type_name);1744 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
1744 struct_type->di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,1747 struct_type->di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,
1745 ZigLLVMTag_DW_structure_type(), type_name,1748 ZigLLVMTag_DW_structure_type(), type_name,
...@@ -1747,11 +1750,14 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f...@@ -1747,11 +1750,14 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f
17471750
1748 for (size_t i = 0; i < field_count; i += 1) {1751 for (size_t i = 0; i < field_count; i += 1) {
1749 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];1752 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
1753 if (type_struct_field->gen_index == SIZE_MAX) {
1754 continue;
1755 }
1750 TypeTableEntry *field_type = type_struct_field->type_entry;1756 TypeTableEntry *field_type = type_struct_field->type_entry;
1751 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref);1757 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref);
1752 uint64_t debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, field_type->type_ref);1758 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);1759 uint64_t debug_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, struct_type->type_ref, type_struct_field->gen_index);
1754 di_element_types[i] = ZigLLVMCreateDebugMemberType(g->dbuilder,1760 di_element_types[type_struct_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,
1755 ZigLLVMTypeToScope(struct_type->di_type), buf_ptr(type_struct_field->name),1761 ZigLLVMTypeToScope(struct_type->di_type), buf_ptr(type_struct_field->name),
1756 nullptr, 0,1762 nullptr, 0,
1757 debug_size_in_bits,1763 debug_size_in_bits,
...@@ -1759,7 +1765,7 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f...@@ -1759,7 +1765,7 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f
1759 debug_offset_in_bits,1765 debug_offset_in_bits,
1760 0, field_type->di_type);1766 0, field_type->di_type);
17611767
1762 assert(di_element_types[i]);1768 assert(di_element_types[type_struct_field->gen_index]);
1763 }1769 }
17641770
1765 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, struct_type->type_ref);1771 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...@@ -1770,7 +1776,7 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f
1770 debug_size_in_bits,1776 debug_size_in_bits,
1771 debug_align_in_bits,1777 debug_align_in_bits,
1772 0,1778 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
1775 ZigLLVMReplaceTemporary(g->dbuilder, struct_type->di_type, replacement_di_type);1781 ZigLLVMReplaceTemporary(g->dbuilder, struct_type->di_type, replacement_di_type);
1776 struct_type->di_type = replacement_di_type;1782 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,...@@ -948,12 +948,10 @@ static IrInstruction *ir_build_const_promise_init(IrBuilder *irb, Scope *scope,
948 const_instruction->base.value.data.x_struct.fields[0].type = struct_type->data.structure.fields[0].type_entry;948 const_instruction->base.value.data.x_struct.fields[0].type = struct_type->data.structure.fields[0].type_entry;
949 const_instruction->base.value.data.x_struct.fields[0].special = ConstValSpecialStatic;949 const_instruction->base.value.data.x_struct.fields[0].special = ConstValSpecialStatic;
950 const_instruction->base.value.data.x_struct.fields[0].data.x_maybe = nullptr;950 const_instruction->base.value.data.x_struct.fields[0].data.x_maybe = nullptr;
951 if (struct_type->data.structure.src_field_count > 1) {951 const_instruction->base.value.data.x_struct.fields[1].type = return_type;
952 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[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].type = struct_type->data.structure.fields[2].type_entry;954 const_instruction->base.value.data.x_struct.fields[2].special = ConstValSpecialUndef;
955 const_instruction->base.value.data.x_struct.fields[2].special = ConstValSpecialUndef;
956 }
957 return &const_instruction->base;955 return &const_instruction->base;
958}956}
959957
...@@ -2741,10 +2739,8 @@ static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode...@@ -2741,10 +2739,8 @@ static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode
2741 return return_inst;2739 return return_inst;
2742 }2740 }
27432741
2744 if (irb->exec->coro_result_ptr_field_ptr) {2742 IrInstruction *result_ptr = ir_build_load_ptr(irb, scope, node, 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);2743 ir_build_store_ptr(irb, scope, node, result_ptr, return_value);
2746 ir_build_store_ptr(irb, scope, node, result_ptr, return_value);
2747 }
2748 IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node,2744 IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node,
2749 get_maybe_type(irb->codegen, irb->codegen->builtin_types.entry_promise));2745 get_maybe_type(irb->codegen, irb->codegen->builtin_types.entry_promise));
2750 // TODO replace replacement_value with @intToPtr(?promise, 0x1) when it doesn't crash zig2746 // 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...@@ -6328,14 +6324,11 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
6328 Buf *awaiter_handle_field_name = buf_create_from_str(AWAITER_HANDLE_FIELD_NAME);6324 Buf *awaiter_handle_field_name = buf_create_from_str(AWAITER_HANDLE_FIELD_NAME);
6329 irb->exec->coro_awaiter_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,6325 irb->exec->coro_awaiter_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,
6330 awaiter_handle_field_name);6326 awaiter_handle_field_name);
6331 if (type_has_bits(return_type)) {6327 Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME);
6332 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);
6333 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);
6334 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);
6335 irb->exec->coro_result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,6331 ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr, coro_result_field_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 }
63396332
63406333
6341 irb->exec->coro_early_final = ir_create_basic_block(irb, scope, "CoroEarlyFinal");6334 irb->exec->coro_early_final = ir_create_basic_block(irb, scope, "CoroEarlyFinal");
test/compile_errors.zig+11
...@@ -1,6 +1,17 @@...@@ -1,6 +1,17 @@
1const tests = @import("tests.zig");1const tests = @import("tests.zig");
22
3pub fn addCases(cases: &tests.CompileErrorContext) void {3pub 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
4 cases.add("var not allowed in structs",15 cases.add("var not allowed in structs",
5 \\export fn entry() void {16 \\export fn entry() void {
6 \\ var s = (struct{v: var}){.v=i32(10)};17 \\ var s = (struct{v: var}){.v=i32(10)};