mirror of
https://github.com/ziglang/zig.git
synced 2026-02-14 21:38:33 +00:00
correct size of types for packed structs
with byte aligned but non-power-of-2 fields such as 24
This commit is contained in:
parent
4709fe1176
commit
cf5108f222
@ -254,15 +254,21 @@ bool type_has_zero_bits_known(TypeTableEntry *type_entry) {
|
||||
|
||||
uint64_t type_size(CodeGen *g, TypeTableEntry *type_entry) {
|
||||
assert(type_is_complete(type_entry));
|
||||
if (type_has_bits(type_entry)) {
|
||||
return LLVMStoreSizeOfType(g->target_data_ref, type_entry->type_ref);
|
||||
} else {
|
||||
TypeTableEntry *canon_type = get_underlying_type(type_entry);
|
||||
|
||||
if (!type_has_bits(type_entry))
|
||||
return 0;
|
||||
|
||||
if (canon_type->id == TypeTableEntryIdStruct && canon_type->data.structure.layout == ContainerLayoutPacked) {
|
||||
uint64_t size_in_bits = type_size_bits(g, type_entry);
|
||||
return (size_in_bits + 7) / 8;
|
||||
}
|
||||
|
||||
return LLVMStoreSizeOfType(g->target_data_ref, type_entry->type_ref);
|
||||
}
|
||||
|
||||
// This has to do with packed structs
|
||||
uint64_t type_size_bits(CodeGen *g, TypeTableEntry *type_entry) {
|
||||
assert(type_is_complete(type_entry));
|
||||
TypeTableEntry *canon_type = get_underlying_type(type_entry);
|
||||
|
||||
if (!type_has_bits(type_entry))
|
||||
@ -531,6 +537,14 @@ TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t
|
||||
|
||||
ensure_complete_type(g, child_type);
|
||||
|
||||
TypeTableEntry *canon_child_type = get_underlying_type(child_type);
|
||||
if (canon_child_type->id == TypeTableEntryIdStruct &&
|
||||
canon_child_type->data.structure.layout == ContainerLayoutPacked &&
|
||||
type_size_bits(g, canon_child_type) != 8 * type_size(g, canon_child_type))
|
||||
{
|
||||
zig_panic("TODO array of packed struct with unaligned size");
|
||||
}
|
||||
|
||||
TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdArray);
|
||||
entry->zero_bits = (array_size == 0) || child_type->zero_bits;
|
||||
|
||||
|
||||
@ -9566,10 +9566,6 @@ static TypeTableEntry *ir_analyze_instruction_set_fn_visible(IrAnalyze *ira,
|
||||
return ira->codegen->builtin_types.entry_void;
|
||||
}
|
||||
|
||||
static bool is_power_of_2(uint64_t x) {
|
||||
return x != 0 && ((x & (~x + 1)) == x);
|
||||
}
|
||||
|
||||
static TypeTableEntry *ir_analyze_instruction_set_global_align(IrAnalyze *ira,
|
||||
IrInstructionSetGlobalAlign *instruction)
|
||||
{
|
||||
|
||||
@ -99,6 +99,10 @@ static inline bool mem_eql_str(const char *mem, size_t mem_len, const char *str)
|
||||
return memcmp(mem, str, mem_len) == 0;
|
||||
}
|
||||
|
||||
static inline bool is_power_of_2(uint64_t x) {
|
||||
return x != 0 && ((x & (~x + 1)) == x);
|
||||
}
|
||||
|
||||
uint32_t int_hash(int i);
|
||||
bool int_eq(int a, int b);
|
||||
uint32_t uint64_hash(uint64_t i);
|
||||
|
||||
@ -270,3 +270,51 @@ fn getB(data: &const BitField1) -> u3 {
|
||||
fn getC(data: &const BitField1) -> u2 {
|
||||
return data.c;
|
||||
}
|
||||
|
||||
const u24 = @intType(false, 24);
|
||||
const Foo24Bits = packed struct {
|
||||
field: u24,
|
||||
};
|
||||
const Foo96Bits = packed struct {
|
||||
a: u24,
|
||||
b: u24,
|
||||
c: u24,
|
||||
d: u24,
|
||||
};
|
||||
|
||||
fn packedStruct24Bits() {
|
||||
@setFnTest(this);
|
||||
|
||||
comptime assert(@sizeOf(Foo24Bits) == 3);
|
||||
comptime assert(@sizeOf(Foo96Bits) == 12);
|
||||
|
||||
var value = Foo96Bits {
|
||||
.a = 0,
|
||||
.b = 0,
|
||||
.c = 0,
|
||||
.d = 0,
|
||||
};
|
||||
value.a += 1;
|
||||
assert(value.a == 1);
|
||||
assert(value.b == 0);
|
||||
assert(value.c == 0);
|
||||
assert(value.d == 0);
|
||||
|
||||
value.b += 1;
|
||||
assert(value.a == 1);
|
||||
assert(value.b == 1);
|
||||
assert(value.c == 0);
|
||||
assert(value.d == 0);
|
||||
|
||||
value.c += 1;
|
||||
assert(value.a == 1);
|
||||
assert(value.b == 1);
|
||||
assert(value.c == 1);
|
||||
assert(value.d == 0);
|
||||
|
||||
value.d += 1;
|
||||
assert(value.a == 1);
|
||||
assert(value.b == 1);
|
||||
assert(value.c == 1);
|
||||
assert(value.d == 1);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user