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...@@ -803,13 +803,7 @@ ZigType *get_array_type(CodeGen *g, ZigType *child_type, uint64_t array_size, Zi
803 }803 }
804 buf_appendf(&entry->name, "]%s", buf_ptr(&child_type->name));804 buf_appendf(&entry->name, "]%s", buf_ptr(&child_type->name));
805805
806 size_t full_array_size;806 size_t full_array_size = array_size + ((sentinel != nullptr) ? 1 : 0);
807 if (array_size == 0) {
808 full_array_size = 0;
809 } else {
810 full_array_size = array_size + ((sentinel != nullptr) ? 1 : 0);
811 }
812
813 entry->size_in_bits = child_type->size_in_bits * full_array_size;807 entry->size_in_bits = child_type->size_in_bits * full_array_size;
814 entry->abi_align = child_type->abi_align;808 entry->abi_align = child_type->abi_align;
815 entry->abi_size = child_type->abi_size * full_array_size;809 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...@@ -1197,7 +1191,8 @@ Error type_val_resolve_zero_bits(CodeGen *g, ZigValue *type_val, ZigType *parent
1197 LazyValueArrayType *lazy_array_type =1191 LazyValueArrayType *lazy_array_type =
1198 reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy);1192 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) {
1201 *is_zero_bits = true;1196 *is_zero_bits = true;
1202 return ErrorNone;1197 return ErrorNone;
1203 }1198 }
...@@ -1452,7 +1447,8 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, ZigV...@@ -1452,7 +1447,8 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, ZigV
1452 case LazyValueIdArrayType: {1447 case LazyValueIdArrayType: {
1453 LazyValueArrayType *lazy_array_type =1448 LazyValueArrayType *lazy_array_type =
1454 reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy);1449 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)
1456 return OnePossibleValueYes;1452 return OnePossibleValueYes;
1457 return type_val_resolve_has_one_possible_value(g, lazy_array_type->elem_type->value);1453 return type_val_resolve_has_one_possible_value(g, lazy_array_type->elem_type->value);
1458 }1454 }
...@@ -5739,7 +5735,8 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {...@@ -5739,7 +5735,8 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
5739 case ZigTypeIdUnreachable:5735 case ZigTypeIdUnreachable:
5740 return OnePossibleValueYes;5736 return OnePossibleValueYes;
5741 case ZigTypeIdArray:5737 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)
5743 return OnePossibleValueYes;5740 return OnePossibleValueYes;
5744 return type_has_one_possible_value(g, type_entry->data.array.child_type);5741 return type_has_one_possible_value(g, type_entry->data.array.child_type);
5745 case ZigTypeIdStruct:5742 case ZigTypeIdStruct:
src/codegen.cpp+3-1
...@@ -3584,7 +3584,9 @@ static bool value_is_all_undef(CodeGen *g, ZigValue *const_val) {...@@ -3584,7 +3584,9 @@ static bool value_is_all_undef(CodeGen *g, ZigValue *const_val) {
3584 }3584 }
3585 return true;3585 return true;
3586 } else if (const_val->type->id == ZigTypeIdArray) {3586 } 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);
3588 } else if (const_val->type->id == ZigTypeIdVector) {3590 } else if (const_val->type->id == ZigTypeIdVector) {
3589 return value_is_all_undef_array(g, const_val, const_val->type->data.vector.len);3591 return value_is_all_undef_array(g, const_val, const_val->type->data.vector.len);
3590 } else {3592 } else {
test/stage1/behavior/array.zig+20
...@@ -376,3 +376,23 @@ test "type deduction for array subscript expression" {...@@ -376,3 +376,23 @@ test "type deduction for array subscript expression" {
376 S.doTheTest();376 S.doTheTest();
377 comptime S.doTheTest();377 comptime S.doTheTest();
378}378}
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}