authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-03-16 18:42:01+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-18 11:10:45-04:00
log1479c28b496e7c1db134b51f23dd2eb934b123bb
tree58c01e7e6308e50c20d352b7ce7106c1152641ef
parent013ada1b59e50bbbab19acab0a79dae72133999a
signaturelock-open Commit is signed but in an unrecognized format.

ir: Correct ABI size calculation for arrays

Zero-length array with a sentinel may not have zero size. Closes #4749

3 files changed, 30 insertions(+), 11 deletions(-)

src/analyze.cpp+7-10
......@@ -803,13 +803,7 @@ ZigType *get_array_type(CodeGen *g, ZigType *child_type, uint64_t array_size, Zi
803803 }
804804 buf_appendf(&entry->name, "]%s", buf_ptr(&child_type->name));
805805
806 size_t full_array_size;
807 if (array_size == 0) {
808 full_array_size = 0;
809 } else {
810 full_array_size = array_size + ((sentinel != nullptr) ? 1 : 0);
811 }
812
806 size_t full_array_size = array_size + ((sentinel != nullptr) ? 1 : 0);
813807 entry->size_in_bits = child_type->size_in_bits * full_array_size;
814808 entry->abi_align = child_type->abi_align;
815809 entry->abi_size = child_type->abi_size * full_array_size;
......@@ -1197,7 +1191,8 @@ Error type_val_resolve_zero_bits(CodeGen *g, ZigValue *type_val, ZigType *parent
11971191 LazyValueArrayType *lazy_array_type =
11981192 reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy);
11991193
1200 if (lazy_array_type->length < 1) {
1194 // The sentinel counts as an extra element
1195 if (lazy_array_type->length == 0 && lazy_array_type->sentinel == nullptr) {
12011196 *is_zero_bits = true;
12021197 return ErrorNone;
12031198 }
......@@ -1452,7 +1447,8 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, ZigV
14521447 case LazyValueIdArrayType: {
14531448 LazyValueArrayType *lazy_array_type =
14541449 reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy);
1455 if (lazy_array_type->length < 1)
1450 // The sentinel counts as an extra element
1451 if (lazy_array_type->length == 0 && lazy_array_type->sentinel == nullptr)
14561452 return OnePossibleValueYes;
14571453 return type_val_resolve_has_one_possible_value(g, lazy_array_type->elem_type->value);
14581454 }
......@@ -5739,7 +5735,8 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
57395735 case ZigTypeIdUnreachable:
57405736 return OnePossibleValueYes;
57415737 case ZigTypeIdArray:
5742 if (type_entry->data.array.len == 0)
5738 // The sentinel counts as an extra element
5739 if (type_entry->data.array.len == 0 && type_entry->data.array.sentinel == nullptr)
57435740 return OnePossibleValueYes;
57445741 return type_has_one_possible_value(g, type_entry->data.array.child_type);
57455742 case ZigTypeIdStruct:
src/codegen.cpp+3-1
......@@ -3584,7 +3584,9 @@ static bool value_is_all_undef(CodeGen *g, ZigValue *const_val) {
35843584 }
35853585 return true;
35863586 } else if (const_val->type->id == ZigTypeIdArray) {
3587 return value_is_all_undef_array(g, const_val, const_val->type->data.array.len);
3587 const size_t full_len = const_val->type->data.array.len +
3588 (const_val->type->data.array.sentinel != nullptr);
3589 return value_is_all_undef_array(g, const_val, full_len);
35883590 } else if (const_val->type->id == ZigTypeIdVector) {
35893591 return value_is_all_undef_array(g, const_val, const_val->type->data.vector.len);
35903592 } else {
test/stage1/behavior/array.zig+20
......@@ -376,3 +376,23 @@ test "type deduction for array subscript expression" {
376376 S.doTheTest();
377377 comptime S.doTheTest();
378378}
379
380test "sentinel element count towards the ABI size calculation" {
381 const S = struct {
382 fn doTheTest() void {
383 const T = packed struct {
384 fill_pre: u8 = 0x55,
385 data: [0:0]u8 = undefined,
386 fill_post: u8 = 0xAA,
387 };
388 var x = T{};
389 var as_slice = mem.asBytes(&x);
390 expectEqual(@as(usize, 3), as_slice.len);
391 expectEqual(@as(u8, 0x55), as_slice[0]);
392 expectEqual(@as(u8, 0xAA), as_slice[2]);
393 }
394 };
395
396 S.doTheTest();
397 comptime S.doTheTest();
398}