ir: Correct ABI size calculation for arrays
Zero-length array with a sentinel may not have zero size. Closes #4749
This commit is contained in:
parent
013ada1b59
commit
1479c28b49
@ -803,13 +803,7 @@ ZigType *get_array_type(CodeGen *g, ZigType *child_type, uint64_t array_size, Zi
|
|||||||
}
|
}
|
||||||
buf_appendf(&entry->name, "]%s", buf_ptr(&child_type->name));
|
buf_appendf(&entry->name, "]%s", buf_ptr(&child_type->name));
|
||||||
|
|
||||||
size_t full_array_size;
|
size_t full_array_size = array_size + ((sentinel != nullptr) ? 1 : 0);
|
||||||
if (array_size == 0) {
|
|
||||||
full_array_size = 0;
|
|
||||||
} else {
|
|
||||||
full_array_size = array_size + ((sentinel != nullptr) ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
entry->size_in_bits = child_type->size_in_bits * full_array_size;
|
entry->size_in_bits = child_type->size_in_bits * full_array_size;
|
||||||
entry->abi_align = child_type->abi_align;
|
entry->abi_align = child_type->abi_align;
|
||||||
entry->abi_size = child_type->abi_size * full_array_size;
|
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
|
|||||||
LazyValueArrayType *lazy_array_type =
|
LazyValueArrayType *lazy_array_type =
|
||||||
reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy);
|
reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy);
|
||||||
|
|
||||||
if (lazy_array_type->length < 1) {
|
// The sentinel counts as an extra element
|
||||||
|
if (lazy_array_type->length == 0 && lazy_array_type->sentinel == nullptr) {
|
||||||
*is_zero_bits = true;
|
*is_zero_bits = true;
|
||||||
return ErrorNone;
|
return ErrorNone;
|
||||||
}
|
}
|
||||||
@ -1452,7 +1447,8 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, ZigV
|
|||||||
case LazyValueIdArrayType: {
|
case LazyValueIdArrayType: {
|
||||||
LazyValueArrayType *lazy_array_type =
|
LazyValueArrayType *lazy_array_type =
|
||||||
reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy);
|
reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy);
|
||||||
if (lazy_array_type->length < 1)
|
// The sentinel counts as an extra element
|
||||||
|
if (lazy_array_type->length == 0 && lazy_array_type->sentinel == nullptr)
|
||||||
return OnePossibleValueYes;
|
return OnePossibleValueYes;
|
||||||
return type_val_resolve_has_one_possible_value(g, lazy_array_type->elem_type->value);
|
return type_val_resolve_has_one_possible_value(g, lazy_array_type->elem_type->value);
|
||||||
}
|
}
|
||||||
@ -5739,7 +5735,8 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
|
|||||||
case ZigTypeIdUnreachable:
|
case ZigTypeIdUnreachable:
|
||||||
return OnePossibleValueYes;
|
return OnePossibleValueYes;
|
||||||
case ZigTypeIdArray:
|
case ZigTypeIdArray:
|
||||||
if (type_entry->data.array.len == 0)
|
// The sentinel counts as an extra element
|
||||||
|
if (type_entry->data.array.len == 0 && type_entry->data.array.sentinel == nullptr)
|
||||||
return OnePossibleValueYes;
|
return OnePossibleValueYes;
|
||||||
return type_has_one_possible_value(g, type_entry->data.array.child_type);
|
return type_has_one_possible_value(g, type_entry->data.array.child_type);
|
||||||
case ZigTypeIdStruct:
|
case ZigTypeIdStruct:
|
||||||
|
@ -3584,7 +3584,9 @@ static bool value_is_all_undef(CodeGen *g, ZigValue *const_val) {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else if (const_val->type->id == ZigTypeIdArray) {
|
} else if (const_val->type->id == ZigTypeIdArray) {
|
||||||
return value_is_all_undef_array(g, const_val, const_val->type->data.array.len);
|
const size_t full_len = const_val->type->data.array.len +
|
||||||
|
(const_val->type->data.array.sentinel != nullptr);
|
||||||
|
return value_is_all_undef_array(g, const_val, full_len);
|
||||||
} else if (const_val->type->id == ZigTypeIdVector) {
|
} else if (const_val->type->id == ZigTypeIdVector) {
|
||||||
return value_is_all_undef_array(g, const_val, const_val->type->data.vector.len);
|
return value_is_all_undef_array(g, const_val, const_val->type->data.vector.len);
|
||||||
} else {
|
} else {
|
||||||
|
@ -376,3 +376,23 @@ test "type deduction for array subscript expression" {
|
|||||||
S.doTheTest();
|
S.doTheTest();
|
||||||
comptime S.doTheTest();
|
comptime S.doTheTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "sentinel element count towards the ABI size calculation" {
|
||||||
|
const S = struct {
|
||||||
|
fn doTheTest() void {
|
||||||
|
const T = packed struct {
|
||||||
|
fill_pre: u8 = 0x55,
|
||||||
|
data: [0:0]u8 = undefined,
|
||||||
|
fill_post: u8 = 0xAA,
|
||||||
|
};
|
||||||
|
var x = T{};
|
||||||
|
var as_slice = mem.asBytes(&x);
|
||||||
|
expectEqual(@as(usize, 3), as_slice.len);
|
||||||
|
expectEqual(@as(u8, 0x55), as_slice[0]);
|
||||||
|
expectEqual(@as(u8, 0xAA), as_slice[2]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
S.doTheTest();
|
||||||
|
comptime S.doTheTest();
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user