| author | |
| committer | |
| log | ce21a784a4bccc66d555b337ebdf98454aaa652f |
| tree | ea84e562d1009ae2ee6121fe190760a8d1dd2543 |
| parent | cf750a58d517c03b38509d9d3189c7b7af41820d |
* Fix packed struct alignment
* Adjust some tests3 files changed, 19 insertions(+), 10 deletions(-)
src/codegen.cpp+7-5| ... | @@ -7265,7 +7265,8 @@ check: switch (const_val->special) { | ... | @@ -7265,7 +7265,8 @@ check: switch (const_val->special) { |
| 7265 | LLVMTypeRef field_ty = LLVMStructGetTypeAtIndex(get_llvm_type(g, type_entry), | 7265 | LLVMTypeRef field_ty = LLVMStructGetTypeAtIndex(get_llvm_type(g, type_entry), |
| 7266 | (unsigned)type_struct_field->gen_index); | 7266 | (unsigned)type_struct_field->gen_index); |
| 7267 | const size_t size_in_bytes = LLVMStoreSizeOfType(g->target_data_ref, field_ty); | 7267 | const size_t size_in_bytes = LLVMStoreSizeOfType(g->target_data_ref, field_ty); |
| 7268 | LLVMTypeRef big_int_type_ref = LLVMIntType(size_in_bytes * 8); | 7268 | const size_t size_in_bits = size_in_bytes * 8; |
| 7269 | LLVMTypeRef big_int_type_ref = LLVMIntType(size_in_bits); | ||
| 7269 | LLVMValueRef val = LLVMConstInt(big_int_type_ref, 0, false); | 7270 | LLVMValueRef val = LLVMConstInt(big_int_type_ref, 0, false); |
| 7270 | size_t used_bits = 0; | 7271 | size_t used_bits = 0; |
| 7271 | for (size_t i = src_field_index; i < src_field_index_end; i += 1) { | 7272 | for (size_t i = src_field_index; i < src_field_index_end; i += 1) { |
| ... | @@ -7278,16 +7279,17 @@ check: switch (const_val->special) { | ... | @@ -7278,16 +7279,17 @@ check: switch (const_val->special) { |
| 7278 | uint32_t packed_bits_size = type_size_bits(g, it_field->type_entry); | 7279 | uint32_t packed_bits_size = type_size_bits(g, it_field->type_entry); |
| 7279 | if (is_big_endian) { | 7280 | if (is_big_endian) { |
| 7280 | LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref, | 7281 | LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref, |
| 7281 | packed_bits_size, false); | 7282 | size_in_bits - used_bits - packed_bits_size, false); |
| 7282 | val = LLVMConstShl(val, shift_amt); | 7283 | LLVMValueRef child_val_shifted = LLVMConstShl(child_val, shift_amt); |
| 7283 | val = LLVMConstOr(val, child_val); | 7284 | val = LLVMConstOr(val, child_val_shifted); |
| 7284 | } else { | 7285 | } else { |
| 7285 | LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref, used_bits, false); | 7286 | LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref, used_bits, false); |
| 7286 | LLVMValueRef child_val_shifted = LLVMConstShl(child_val, shift_amt); | 7287 | LLVMValueRef child_val_shifted = LLVMConstShl(child_val, shift_amt); |
| 7287 | val = LLVMConstOr(val, child_val_shifted); | 7288 | val = LLVMConstOr(val, child_val_shifted); |
| 7288 | used_bits += packed_bits_size; | ||
| 7289 | } | 7289 | } |
| 7290 | used_bits += packed_bits_size; | ||
| 7290 | } | 7291 | } |
| 7292 | assert(size_in_bits >= used_bits); | ||
| 7291 | if (LLVMGetTypeKind(field_ty) != LLVMArrayTypeKind) { | 7293 | if (LLVMGetTypeKind(field_ty) != LLVMArrayTypeKind) { |
| 7292 | assert(LLVMGetTypeKind(field_ty) == LLVMIntegerTypeKind); | 7294 | assert(LLVMGetTypeKind(field_ty) == LLVMIntegerTypeKind); |
| 7293 | fields[type_struct_field->gen_index] = val; | 7295 | fields[type_struct_field->gen_index] = val; |
test/stage1/behavior/ptrcast.zig+7-3| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 2 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const builtin = std.builtin; | ||
| 3 | const expect = std.testing.expect; | 3 | const expect = std.testing.expect; |
| 4 | 4 | ||
| 5 | test "reinterpret bytes as integer with nonzero offset" { | 5 | test "reinterpret bytes as integer with nonzero offset" { |
| ... | @@ -36,8 +36,12 @@ fn testReinterpretBytesAsExternStruct() void { | ... | @@ -36,8 +36,12 @@ fn testReinterpretBytesAsExternStruct() void { |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | test "reinterpret struct field at comptime" { | 38 | test "reinterpret struct field at comptime" { |
| 39 | const numLittle = comptime Bytes.init(0x12345678); | 39 | const numNative = comptime Bytes.init(0x12345678); |
| 40 | expect(std.mem.eql(u8, &[_]u8{ 0x78, 0x56, 0x34, 0x12 }, &numLittle.bytes)); | 40 | if (builtin.endian != .Little) { |
| 41 | expect(std.mem.eql(u8, &[_]u8{ 0x12, 0x34, 0x56, 0x78 }, &numNative.bytes)); | ||
| 42 | } else { | ||
| 43 | expect(std.mem.eql(u8, &[_]u8{ 0x78, 0x56, 0x34, 0x12 }, &numNative.bytes)); | ||
| 44 | } | ||
| 41 | } | 45 | } |
| 42 | 46 | ||
| 43 | const Bytes = struct { | 47 | const Bytes = struct { |
test/stage1/behavior/struct.zig+5-2| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const builtin = std.builtin; | ||
| 2 | const expect = std.testing.expect; | 3 | const expect = std.testing.expect; |
| 3 | const expectEqual = std.testing.expectEqual; | 4 | const expectEqual = std.testing.expectEqual; |
| 4 | const expectEqualSlices = std.testing.expectEqualSlices; | 5 | const expectEqualSlices = std.testing.expectEqualSlices; |
| 5 | const builtin = @import("builtin"); | ||
| 6 | const maxInt = std.math.maxInt; | 6 | const maxInt = std.math.maxInt; |
| 7 | const StructWithNoFields = struct { | 7 | const StructWithNoFields = struct { |
| 8 | fn add(a: i32, b: i32) i32 { | 8 | fn add(a: i32, b: i32) i32 { |
| ... | @@ -407,7 +407,10 @@ const Bitfields = packed struct { | ... | @@ -407,7 +407,10 @@ const Bitfields = packed struct { |
| 407 | }; | 407 | }; |
| 408 | 408 | ||
| 409 | test "native bit field understands endianness" { | 409 | test "native bit field understands endianness" { |
| 410 | var all: u64 = 0x7765443322221111; | 410 | var all: u64 = if (builtin.endian != .Little) |
| 411 | 0x1111222233445677 | ||
| 412 | else | ||
| 413 | 0x7765443322221111; | ||
| 411 | var bytes: [8]u8 = undefined; | 414 | var bytes: [8]u8 = undefined; |
| 412 | @memcpy(&bytes, @ptrCast([*]u8, &all), 8); | 415 | @memcpy(&bytes, @ptrCast([*]u8, &all), 8); |
| 413 | var bitfields = @ptrCast(*Bitfields, &bytes).*; | 416 | var bitfields = @ptrCast(*Bitfields, &bytes).*; |