authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-01-27 18:30:36-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-01-27 18:30:36-05:00
logf66ac9a5e704d9900d9e21cb482d7487a02e7b34
tree3353cea0f40328a854a06f83f1562cc34812ae8f
parentad3e2a5da07fbfe02e0152eb3fc408a7bcf36e3c

fix crash when align 1 field before self referential...

...align 8 field as slice return type closes #723

2 files changed, 25 insertions(+), 5 deletions(-)

src/analyze.cpp+11-5
...@@ -362,8 +362,10 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type...@@ -362,8 +362,10 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type
362 } else {362 } else {
363 assert(bit_offset == 0);363 assert(bit_offset == 0);
364 parent_pointer = &child_type->pointer_parent[(is_const ? 1 : 0)];364 parent_pointer = &child_type->pointer_parent[(is_const ? 1 : 0)];
365 if (*parent_pointer)365 if (*parent_pointer) {
366 assert((*parent_pointer)->data.pointer.alignment == byte_alignment);
366 return *parent_pointer;367 return *parent_pointer;
368 }
367 }369 }
368370
369 type_ensure_zero_bits_known(g, child_type);371 type_ensure_zero_bits_known(g, child_type);
...@@ -2356,6 +2358,7 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {...@@ -2356,6 +2358,7 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
2356 bool create_enum_type = decl_node->data.container_decl.auto_enum || (enum_type_node == nullptr && want_safety);2358 bool create_enum_type = decl_node->data.container_decl.auto_enum || (enum_type_node == nullptr && want_safety);
2357 bool *covered_enum_fields;2359 bool *covered_enum_fields;
2358 ZigLLVMDIEnumerator **di_enumerators;2360 ZigLLVMDIEnumerator **di_enumerators;
2361 uint32_t abi_alignment_so_far;
2359 if (create_enum_type) {2362 if (create_enum_type) {
2360 occupied_tag_values.init(field_count);2363 occupied_tag_values.init(field_count);
23612364
...@@ -2377,7 +2380,7 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {...@@ -2377,7 +2380,7 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
2377 } else {2380 } else {
2378 tag_int_type = get_smallest_unsigned_int_type(g, field_count - 1);2381 tag_int_type = get_smallest_unsigned_int_type(g, field_count - 1);
2379 }2382 }
2380 union_type->data.unionation.abi_alignment = get_abi_alignment(g, tag_int_type);2383 abi_alignment_so_far = get_abi_alignment(g, tag_int_type);
23812384
2382 tag_type = new_type_table_entry(TypeTableEntryIdEnum);2385 tag_type = new_type_table_entry(TypeTableEntryIdEnum);
2383 buf_resize(&tag_type->name, 0);2386 buf_resize(&tag_type->name, 0);
...@@ -2408,9 +2411,10 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {...@@ -2408,9 +2411,10 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
2408 }2411 }
2409 tag_type = enum_type;2412 tag_type = enum_type;
2410 covered_enum_fields = allocate<bool>(enum_type->data.enumeration.src_field_count);2413 covered_enum_fields = allocate<bool>(enum_type->data.enumeration.src_field_count);
2411 union_type->data.unionation.abi_alignment = get_abi_alignment(g, enum_type);2414 abi_alignment_so_far = get_abi_alignment(g, enum_type);
2412 } else {2415 } else {
2413 tag_type = nullptr;2416 tag_type = nullptr;
2417 abi_alignment_so_far = 0;
2414 }2418 }
2415 union_type->data.unionation.tag_type = tag_type;2419 union_type->data.unionation.tag_type = tag_type;
24162420
...@@ -2508,12 +2512,14 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {...@@ -2508,12 +2512,14 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
2508 uint32_t field_align_bytes = get_abi_alignment(g, field_type);2512 uint32_t field_align_bytes = get_abi_alignment(g, field_type);
2509 if (field_align_bytes > biggest_align_bytes) {2513 if (field_align_bytes > biggest_align_bytes) {
2510 biggest_align_bytes = field_align_bytes;2514 biggest_align_bytes = field_align_bytes;
2511 if (biggest_align_bytes > union_type->data.unionation.abi_alignment) {2515 if (biggest_align_bytes > abi_alignment_so_far) {
2512 union_type->data.unionation.abi_alignment = biggest_align_bytes;2516 abi_alignment_so_far = biggest_align_bytes;
2513 }2517 }
2514 }2518 }
2515 }2519 }
25162520
2521 union_type->data.unionation.abi_alignment = abi_alignment_so_far;
2522
2517 if (union_type->data.unionation.is_invalid)2523 if (union_type->data.unionation.is_invalid)
2518 return;2524 return;
25192525
test/cases/struct.zig+14
...@@ -404,3 +404,17 @@ test "native bit field understands endianness" {...@@ -404,3 +404,17 @@ test "native bit field understands endianness" {
404 assert(bitfields.f6 == 0x6);404 assert(bitfields.f6 == 0x6);
405 assert(bitfields.f7 == 0x77);405 assert(bitfields.f7 == 0x77);
406}406}
407
408test "align 1 field before self referential align 8 field as slice return type" {
409 const result = alloc(Expr);
410 assert(result.len == 0);
411}
412
413const Expr = union(enum) {
414 Literal: u8,
415 Question: &Expr,
416};
417
418fn alloc(comptime T: type) []T {
419 return []T{};
420}