authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-13 12:44:30-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-13 12:44:30-04:00
log12ff91c1c99da11dcaab1e4a1adb6a6917ef4881
tree7653b6a83dc5cd5861173445cb30726248506be6
parent8a9289996ab8ed7da2f7e0c6df9fe2bd9a3e0b7b
signature Commit is signed but in an unrecognized format.

alignment of structs no longer depends on LLVM

fixes async function tests in optimized builds

7 files changed, 204 insertions(+), 59 deletions(-)

BRANCH_TODO+1
......@@ -1,3 +1,4 @@
1 * alignment of variables not being respected in async functions
12 * for loops need to spill the index. other payload captures probably also need to spill
23 * compile error (instead of crashing) for trying to get @Frame of generic function
34 * compile error (instead of crashing) for trying to async call and passing @Frame of wrong function
src/all_types.hpp+3
......@@ -1148,6 +1148,8 @@ struct ZigTypeOptional {
11481148struct ZigTypeErrorUnion {
11491149 ZigType *err_set_type;
11501150 ZigType *payload_type;
1151 size_t pad_bytes;
1152 LLVMTypeRef pad_llvm_type;
11511153};
11521154
11531155struct ZigTypeErrorSet {
......@@ -3564,6 +3566,7 @@ struct IrInstructionAllocaGen {
35643566
35653567 uint32_t align;
35663568 const char *name_hint;
3569 size_t field_index;
35673570};
35683571
35693572struct IrInstructionEndExpr {
src/analyze.cpp+101-32
......@@ -630,6 +630,7 @@ ZigType *get_error_union_type(CodeGen *g, ZigType *err_set_type, ZigType *payloa
630630 size_t field2_offset = next_field_offset(0, entry->abi_align, field_sizes[0], field_aligns[1]);
631631 entry->abi_size = next_field_offset(field2_offset, entry->abi_align, field_sizes[1], entry->abi_align);
632632 entry->size_in_bits = entry->abi_size * 8;
633 entry->data.error_union.pad_bytes = entry->abi_size - (field2_offset + field_sizes[1]);
633634 }
634635
635636 g->type_table.put(type_id, entry);
......@@ -1499,7 +1500,7 @@ bool type_is_invalid(ZigType *type_entry) {
14991500}
15001501
15011502
1502ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],
1503static ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],
15031504 ZigType *field_types[], size_t field_count, unsigned min_abi_align)
15041505{
15051506 ZigType *struct_type = new_type_table_entry(ZigTypeIdStruct);
......@@ -1524,10 +1525,6 @@ ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_na
15241525 if (field->type_entry->abi_align > abi_align) {
15251526 abi_align = field->type_entry->abi_align;
15261527 }
1527 field->gen_index = struct_type->data.structure.gen_field_count;
1528 struct_type->data.structure.gen_field_count += 1;
1529 } else {
1530 field->gen_index = SIZE_MAX;
15311528 }
15321529
15331530 auto prev_entry = struct_type->data.structure.fields_by_name.put_unique(field->name, field);
......@@ -1537,14 +1534,16 @@ ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_na
15371534 size_t next_offset = 0;
15381535 for (size_t i = 0; i < field_count; i += 1) {
15391536 TypeStructField *field = &struct_type->data.structure.fields[i];
1540 if (field->gen_index == SIZE_MAX)
1537 if (!type_has_bits(field->type_entry))
15411538 continue;
1539
15421540 field->offset = next_offset;
1541
1542 // find the next non-zero-byte field for offset calculations
15431543 size_t next_src_field_index = i + 1;
15441544 for (; next_src_field_index < field_count; next_src_field_index += 1) {
1545 if (struct_type->data.structure.fields[next_src_field_index].gen_index != SIZE_MAX) {
1545 if (type_has_bits(struct_type->data.structure.fields[next_src_field_index].type_entry))
15461546 break;
1547 }
15481547 }
15491548 size_t next_abi_align = (next_src_field_index == field_count) ?
15501549 abi_align : struct_type->data.structure.fields[next_src_field_index].type_entry->abi_align;
......@@ -5304,6 +5303,7 @@ static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {
53045303
53055304 for (size_t alloca_i = 0; alloca_i < fn->alloca_gen_list.length; alloca_i += 1) {
53065305 IrInstructionAllocaGen *instruction = fn->alloca_gen_list.at(alloca_i);
5306 instruction->field_index = SIZE_MAX;
53075307 ZigType *ptr_type = instruction->base.value.type;
53085308 assert(ptr_type->id == ZigTypeIdPointer);
53095309 ZigType *child_type = ptr_type->data.pointer.child_type;
......@@ -5327,6 +5327,7 @@ static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {
53275327 } else {
53285328 name = buf_ptr(buf_sprintf("%s.%" ZIG_PRI_usize, instruction->name_hint, alloca_i));
53295329 }
5330 instruction->field_index = field_types.length;
53305331 field_names.append(name);
53315332 field_types.append(child_type);
53325333 }
......@@ -5949,6 +5950,15 @@ ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) {
59495950 entry->llvm_type = LLVMIntType(size_in_bits);
59505951 entry->abi_size = LLVMABISizeOfType(g->target_data_ref, entry->llvm_type);
59515952 entry->abi_align = LLVMABIAlignmentOfType(g->target_data_ref, entry->llvm_type);
5953
5954 if (size_in_bits >= 128) {
5955 // Override the incorrect alignment reported by LLVM. Clang does this as well.
5956 // On x86_64 there are some instructions like CMPXCHG16B which require this.
5957 // On all targets, integers 128 bits and above have ABI alignment of 16.
5958 // See: https://github.com/ziglang/zig/issues/2987
5959 assert(entry->abi_align == 8); // if this trips we can remove the workaround
5960 entry->abi_align = 16;
5961 }
59525962 }
59535963
59545964 const char u_or_i = is_signed ? 'i' : 'u';
......@@ -6810,10 +6820,9 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
68106820 }
68116821
68126822 size_t field_count = struct_type->data.structure.src_field_count;
6813 size_t gen_field_count = struct_type->data.structure.gen_field_count;
6814 LLVMTypeRef *element_types = allocate<LLVMTypeRef>(gen_field_count);
6823 // Every field could potentially have a generated padding field after it.
6824 LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count * 2);
68156825
6816 size_t gen_field_index = 0;
68176826 bool packed = (struct_type->data.structure.layout == ContainerLayoutPacked);
68186827 size_t packed_bits_offset = 0;
68196828 size_t first_packed_bits_offset_misalign = SIZE_MAX;
......@@ -6821,20 +6830,36 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
68216830
68226831 // trigger all the recursive get_llvm_type calls
68236832 for (size_t i = 0; i < field_count; i += 1) {
6824 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
6825 ZigType *field_type = type_struct_field->type_entry;
6833 TypeStructField *field = &struct_type->data.structure.fields[i];
6834 ZigType *field_type = field->type_entry;
68266835 if (!type_has_bits(field_type))
68276836 continue;
68286837 (void)get_llvm_type(g, field_type);
68296838 if (struct_type->data.structure.resolve_status >= wanted_resolve_status) return;
68306839 }
68316840
6832 for (size_t i = 0; i < field_count; i += 1) {
6833 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
6834 ZigType *field_type = type_struct_field->type_entry;
6841 size_t gen_field_index = 0;
68356842
6843 // Calculate what LLVM thinks the ABI align of the struct will be. We do this to avoid
6844 // inserting padding bytes where LLVM would do it automatically.
6845 size_t llvm_struct_abi_align = 0;
6846 for (size_t i = 0; i < field_count; i += 1) {
6847 ZigType *field_type = struct_type->data.structure.fields[i].type_entry;
68366848 if (!type_has_bits(field_type))
68376849 continue;
6850 LLVMTypeRef field_llvm_type = get_llvm_type(g, field_type);
6851 size_t llvm_field_abi_align = LLVMABIAlignmentOfType(g->target_data_ref, field_llvm_type);
6852 llvm_struct_abi_align = max(llvm_struct_abi_align, llvm_field_abi_align);
6853 }
6854
6855 for (size_t i = 0; i < field_count; i += 1) {
6856 TypeStructField *field = &struct_type->data.structure.fields[i];
6857 ZigType *field_type = field->type_entry;
6858
6859 if (!type_has_bits(field_type)) {
6860 field->gen_index = SIZE_MAX;
6861 continue;
6862 }
68386863
68396864 if (packed) {
68406865 size_t field_size_in_bits = type_size_bits(g, field_type);
......@@ -6871,11 +6896,44 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
68716896 llvm_type = get_llvm_type(g, field_type);
68726897 }
68736898 element_types[gen_field_index] = llvm_type;
6874
6899 field->gen_index = gen_field_index;
68756900 gen_field_index += 1;
6901
6902 // find the next non-zero-byte field for offset calculations
6903 size_t next_src_field_index = i + 1;
6904 for (; next_src_field_index < field_count; next_src_field_index += 1) {
6905 if (type_has_bits(struct_type->data.structure.fields[next_src_field_index].type_entry))
6906 break;
6907 }
6908 size_t next_abi_align = (next_src_field_index == field_count) ?
6909 struct_type->abi_align :
6910 struct_type->data.structure.fields[next_src_field_index].type_entry->abi_align;
6911 size_t llvm_next_abi_align = (next_src_field_index == field_count) ?
6912 llvm_struct_abi_align :
6913 LLVMABIAlignmentOfType(g->target_data_ref,
6914 get_llvm_type(g, struct_type->data.structure.fields[next_src_field_index].type_entry));
6915
6916 size_t next_offset = next_field_offset(field->offset, struct_type->abi_align,
6917 field_type->abi_size, next_abi_align);
6918 size_t llvm_next_offset = next_field_offset(field->offset, llvm_struct_abi_align,
6919 LLVMABISizeOfType(g->target_data_ref, llvm_type), llvm_next_abi_align);
6920
6921 assert(next_offset >= llvm_next_offset);
6922 if (next_offset > llvm_next_offset) {
6923 size_t pad_bytes = next_offset - (field->offset + field_type->abi_size);
6924 if (pad_bytes != 0) {
6925 LLVMTypeRef pad_llvm_type = LLVMArrayType(LLVMInt8Type(), pad_bytes);
6926 element_types[gen_field_index] = pad_llvm_type;
6927 gen_field_index += 1;
6928 }
6929 }
68766930 }
68776931 debug_field_count += 1;
68786932 }
6933 if (!packed) {
6934 struct_type->data.structure.gen_field_count = gen_field_index;
6935 }
6936
68796937 if (first_packed_bits_offset_misalign != SIZE_MAX) {
68806938 size_t full_bit_count = packed_bits_offset - first_packed_bits_offset_misalign;
68816939 size_t full_abi_size = get_abi_size_bytes(full_bit_count, g->pointer_size_bytes);
......@@ -6884,19 +6942,20 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
68846942 }
68856943
68866944 if (type_has_bits(struct_type)) {
6887 LLVMStructSetBody(struct_type->llvm_type, element_types, (unsigned)gen_field_count, packed);
6945 LLVMStructSetBody(struct_type->llvm_type, element_types,
6946 (unsigned)struct_type->data.structure.gen_field_count, packed);
68886947 }
68896948
68906949 ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(debug_field_count);
68916950 size_t debug_field_index = 0;
68926951 for (size_t i = 0; i < field_count; i += 1) {
6893 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
6894 size_t gen_field_index = type_struct_field->gen_index;
6952 TypeStructField *field = &struct_type->data.structure.fields[i];
6953 size_t gen_field_index = field->gen_index;
68956954 if (gen_field_index == SIZE_MAX) {
68966955 continue;
68976956 }
68986957
6899 ZigType *field_type = type_struct_field->type_entry;
6958 ZigType *field_type = field->type_entry;
69006959
69016960 // if the field is a function, actually the debug info should be a pointer.
69026961 ZigLLVMDIType *field_di_type;
......@@ -6914,13 +6973,13 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
69146973 uint64_t debug_align_in_bits;
69156974 uint64_t debug_offset_in_bits;
69166975 if (packed) {
6917 debug_size_in_bits = type_struct_field->type_entry->size_in_bits;
6918 debug_align_in_bits = 8 * type_struct_field->type_entry->abi_align;
6919 debug_offset_in_bits = 8 * type_struct_field->offset + type_struct_field->bit_offset_in_host;
6976 debug_size_in_bits = field->type_entry->size_in_bits;
6977 debug_align_in_bits = 8 * field->type_entry->abi_align;
6978 debug_offset_in_bits = 8 * field->offset + field->bit_offset_in_host;
69206979 } else {
69216980 debug_size_in_bits = 8 * get_store_size_bytes(field_type->size_in_bits);
69226981 debug_align_in_bits = 8 * field_type->abi_align;
6923 debug_offset_in_bits = 8 * type_struct_field->offset;
6982 debug_offset_in_bits = 8 * field->offset;
69246983 }
69256984 unsigned line;
69266985 if (decl_node != nullptr) {
......@@ -6930,7 +6989,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
69306989 line = 0;
69316990 }
69326991 di_element_types[debug_field_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,
6933 ZigLLVMTypeToScope(struct_type->llvm_di_type), buf_ptr(type_struct_field->name),
6992 ZigLLVMTypeToScope(struct_type->llvm_di_type), buf_ptr(field->name),
69346993 di_file, line,
69356994 debug_size_in_bits,
69366995 debug_align_in_bits,
......@@ -7171,7 +7230,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
71717230 union_type->data.unionation.resolve_status = ResolveStatusLLVMFull;
71727231}
71737232
7174static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type) {
7233static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) {
71757234 if (type->llvm_di_type != nullptr) return;
71767235
71777236 if (!type_has_bits(type)) {
......@@ -7200,7 +7259,7 @@ static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type) {
72007259 uint64_t debug_align_in_bits = 8*type->abi_align;
72017260 type->llvm_di_type = ZigLLVMCreateDebugPointerType(g->dbuilder, elem_type->llvm_di_type,
72027261 debug_size_in_bits, debug_align_in_bits, buf_ptr(&type->name));
7203 assertNoError(type_resolve(g, elem_type, ResolveStatusLLVMFull));
7262 assertNoError(type_resolve(g, elem_type, wanted_resolve_status));
72047263 } else {
72057264 ZigType *host_int_type = get_int_type(g, false, type->data.pointer.host_int_bytes * 8);
72067265 LLVMTypeRef host_int_llvm_type = get_llvm_type(g, host_int_type);
......@@ -7326,10 +7385,17 @@ static void resolve_llvm_types_error_union(CodeGen *g, ZigType *type) {
73267385 } else {
73277386 LLVMTypeRef err_set_llvm_type = get_llvm_type(g, err_set_type);
73287387 LLVMTypeRef payload_llvm_type = get_llvm_type(g, payload_type);
7329 LLVMTypeRef elem_types[2];
7388 LLVMTypeRef elem_types[3];
73307389 elem_types[err_union_err_index] = err_set_llvm_type;
73317390 elem_types[err_union_payload_index] = payload_llvm_type;
7391
73327392 type->llvm_type = LLVMStructType(elem_types, 2, false);
7393 if (LLVMABISizeOfType(g->target_data_ref, type->llvm_type) != type->abi_size) {
7394 // we need to do our own padding
7395 type->data.error_union.pad_llvm_type = LLVMArrayType(LLVMInt8Type(), type->data.error_union.pad_bytes);
7396 elem_types[2] = type->data.error_union.pad_llvm_type;
7397 type->llvm_type = LLVMStructType(elem_types, 3, false);
7398 }
73337399
73347400 ZigLLVMDIScope *compile_unit_scope = ZigLLVMCompileUnitToScope(g->compile_unit);
73357401 ZigLLVMDIFile *di_file = nullptr;
......@@ -7511,6 +7577,7 @@ static void resolve_llvm_types_fn_type(CodeGen *g, ZigType *fn_type) {
75117577}
75127578
75137579void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn) {
7580 Error err;
75147581 if (fn->raw_di_type != nullptr) return;
75157582
75167583 ZigType *fn_type = fn->type_entry;
......@@ -7529,8 +7596,10 @@ void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn) {
75297596
75307597 ZigType *frame_type = get_coro_frame_type(g, fn);
75317598 ZigType *ptr_type = get_pointer_to_type(g, frame_type, false);
7532 gen_param_types.append(get_llvm_type(g, ptr_type));
7533 param_di_types.append(get_llvm_di_type(g, ptr_type));
7599 if ((err = type_resolve(g, ptr_type, ResolveStatusLLVMFwdDecl)))
7600 zig_unreachable();
7601 gen_param_types.append(ptr_type->llvm_type);
7602 param_di_types.append(ptr_type->llvm_di_type);
75347603
75357604 // this parameter is used to pass the result pointer when await completes
75367605 gen_param_types.append(get_llvm_type(g, g->builtin_types.entry_usize));
......@@ -7726,7 +7795,7 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r
77267795 case ZigTypeIdUnion:
77277796 return resolve_llvm_types_union(g, type, wanted_resolve_status);
77287797 case ZigTypeIdPointer:
7729 return resolve_llvm_types_pointer(g, type);
7798 return resolve_llvm_types_pointer(g, type, wanted_resolve_status);
77307799 case ZigTypeIdInt:
77317800 return resolve_llvm_types_integer(g, type);
77327801 case ZigTypeIdOptional:
src/analyze.hpp-2
......@@ -38,8 +38,6 @@ ZigType *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x);
3838ZigType *get_error_union_type(CodeGen *g, ZigType *err_set_type, ZigType *payload_type);
3939ZigType *get_bound_fn_type(CodeGen *g, ZigFn *fn_entry);
4040ZigType *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *full_name, Buf *bare_name);
41ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],
42 ZigType *field_types[], size_t field_count, unsigned min_abi_align);
4341ZigType *get_test_fn_type(CodeGen *g);
4442ZigType *get_any_frame_type(CodeGen *g, ZigType *result_type);
4543bool handle_is_ptr(ZigType *type_entry);
src/codegen.cpp+36-22
......@@ -3765,29 +3765,17 @@ static void render_async_spills(CodeGen *g) {
37653765 gen_var_debug_decl(g, var);
37663766 }
37673767 }
3768 // label (grep this): [coro_frame_struct_layout]
3769 if (codegen_fn_has_err_ret_tracing_stack(g, g->cur_fn, true)) {
3770 async_var_index += 2;
3771 }
3768
3769 ZigType *frame_type = g->cur_fn->frame_type->data.frame.locals_struct;
3770
37723771 for (size_t alloca_i = 0; alloca_i < g->cur_fn->alloca_gen_list.length; alloca_i += 1) {
37733772 IrInstructionAllocaGen *instruction = g->cur_fn->alloca_gen_list.at(alloca_i);
3774 ZigType *ptr_type = instruction->base.value.type;
3775 assert(ptr_type->id == ZigTypeIdPointer);
3776 ZigType *child_type = ptr_type->data.pointer.child_type;
3777 if (!type_has_bits(child_type))
3778 continue;
3779 if (instruction->base.ref_count == 0)
3773 if (instruction->field_index == SIZE_MAX)
37803774 continue;
3781 if (instruction->base.value.special != ConstValSpecialRuntime) {
3782 if (const_ptr_pointee(nullptr, g, &instruction->base.value, nullptr)->special !=
3783 ConstValSpecialRuntime)
3784 {
3785 continue;
3786 }
3787 }
3788 instruction->base.llvm_value = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, async_var_index,
3775
3776 size_t gen_index = frame_type->data.structure.fields[instruction->field_index].gen_index;
3777 instruction->base.llvm_value = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, gen_index,
37893778 instruction->name_hint);
3790 async_var_index += 1;
37913779 }
37923780}
37933781
......@@ -6363,6 +6351,9 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
63636351 break;
63646352 }
63656353
6354 if ((err = type_resolve(g, type_entry, ResolveStatusLLVMFull)))
6355 zig_unreachable();
6356
63666357 switch (type_entry->id) {
63676358 case ZigTypeIdInt:
63686359 return bigint_to_llvm_const(get_llvm_type(g, type_entry), &const_val->data.x_bigint);
......@@ -6434,6 +6425,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
64346425 LLVMValueRef *fields = allocate<LLVMValueRef>(type_entry->data.structure.gen_field_count);
64356426 size_t src_field_count = type_entry->data.structure.src_field_count;
64366427 bool make_unnamed_struct = false;
6428 assert(type_entry->data.structure.resolve_status == ResolveStatusLLVMFull);
64376429 if (type_entry->data.structure.layout == ContainerLayoutPacked) {
64386430 size_t src_field_index = 0;
64396431 while (src_field_index < src_field_count) {
......@@ -6503,6 +6495,22 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
65036495 LLVMValueRef val = gen_const_val(g, field_val, "");
65046496 fields[type_struct_field->gen_index] = val;
65056497 make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(g, field_val->type, val);
6498
6499 size_t end_pad_gen_index = (i + 1 < src_field_count) ?
6500 type_entry->data.structure.fields[i + 1].gen_index :
6501 type_entry->data.structure.gen_field_count;
6502 size_t next_offset = (i + 1 < src_field_count) ?
6503 type_entry->data.structure.fields[i + 1].offset : type_entry->abi_size;
6504 if (end_pad_gen_index != SIZE_MAX) {
6505 for (size_t gen_i = type_struct_field->gen_index + 1; gen_i < end_pad_gen_index;
6506 gen_i += 1)
6507 {
6508 size_t pad_bytes = next_offset -
6509 (type_struct_field->offset + type_struct_field->type_entry->abi_size);
6510 LLVMTypeRef llvm_array_type = LLVMArrayType(LLVMInt8Type(), pad_bytes);
6511 fields[gen_i] = LLVMGetUndef(llvm_array_type);
6512 }
6513 }
65066514 }
65076515 }
65086516 if (make_unnamed_struct) {
......@@ -6690,13 +6698,18 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
66906698 err_payload_value = gen_const_val(g, payload_val, "");
66916699 make_unnamed_struct = is_llvm_value_unnamed_type(g, payload_val->type, err_payload_value);
66926700 }
6693 LLVMValueRef fields[2];
6701 LLVMValueRef fields[3];
66946702 fields[err_union_err_index] = err_tag_value;
66956703 fields[err_union_payload_index] = err_payload_value;
6704 size_t field_count = 2;
6705 if (type_entry->data.error_union.pad_llvm_type != nullptr) {
6706 fields[2] = LLVMGetUndef(type_entry->data.error_union.pad_llvm_type);
6707 field_count = 3;
6708 }
66966709 if (make_unnamed_struct) {
6697 return LLVMConstStruct(fields, 2, false);
6710 return LLVMConstStruct(fields, field_count, false);
66986711 } else {
6699 return LLVMConstNamedStruct(get_llvm_type(g, type_entry), fields, 2);
6712 return LLVMConstNamedStruct(get_llvm_type(g, type_entry), fields, field_count);
67006713 }
67016714 }
67026715 }
......@@ -7139,6 +7152,7 @@ static void do_code_gen(CodeGen *g) {
71397152 }
71407153
71417154 if (is_async) {
7155 (void)get_llvm_type(g, fn_table_entry->frame_type);
71427156 g->cur_resume_block_count = 0;
71437157
71447158 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
std/event/channel.zig+1-3
......@@ -307,11 +307,9 @@ test "std.event.Channel" {
307307 // https://github.com/ziglang/zig/issues/1908
308308 if (builtin.single_threaded) return error.SkipZigTest;
309309
310 const allocator = std.heap.direct_allocator;
311
312310 var loop: Loop = undefined;
313311 // TODO make a multi threaded test
314 try loop.initSingleThreaded(allocator);
312 try loop.initSingleThreaded(std.heap.direct_allocator);
315313 defer loop.deinit();
316314
317315 const channel = try Channel(i32).create(&loop, 0);
test/stage1/behavior/align.zig+62
......@@ -228,3 +228,65 @@ test "alignment of extern() void" {
228228}
229229
230230extern fn nothing() void {}
231
232test "return error union with 128-bit integer" {
233 expect(3 == try give());
234}
235fn give() anyerror!u128 {
236 return 3;
237}
238
239test "alignment of >= 128-bit integer type" {
240 expect(@alignOf(u128) == 16);
241 expect(@alignOf(u129) == 16);
242}
243
244test "alignment of struct with 128-bit field" {
245 expect(@alignOf(struct {
246 x: u128,
247 }) == 16);
248
249 comptime {
250 expect(@alignOf(struct {
251 x: u128,
252 }) == 16);
253 }
254}
255
256test "size of extern struct with 128-bit field" {
257 expect(@sizeOf(extern struct {
258 x: u128,
259 y: u8,
260 }) == 32);
261
262 comptime {
263 expect(@sizeOf(extern struct {
264 x: u128,
265 y: u8,
266 }) == 32);
267 }
268}
269
270const DefaultAligned = struct {
271 nevermind: u32,
272 badguy: i128,
273};
274
275test "read 128-bit field from default aligned struct in stack memory" {
276 var default_aligned = DefaultAligned{
277 .nevermind = 1,
278 .badguy = 12,
279 };
280 expect((@ptrToInt(&default_aligned.badguy) % 16) == 0);
281 expect(12 == default_aligned.badguy);
282}
283
284var default_aligned_global = DefaultAligned{
285 .nevermind = 1,
286 .badguy = 12,
287};
288
289test "read 128-bit field from default aligned struct in global memory" {
290 expect((@ptrToInt(&default_aligned_global.badguy) % 16) == 0);
291 expect(12 == default_aligned_global.badguy);
292}