authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-20 16:13:36+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-20 17:07:12+03:00
logd41dd499a9fd42be3a30018dccb6a9a9fbf43f3d
treeb87a16047c8c386c3458ed12c37ea8c3dba73570
parentde62bd06472e5603fd2afb6f50d688d54f4098b4

stage2 llvm: fix handling of pointer fields in packed structs


2 files changed, 30 insertions(+), 1 deletions(-)

src/codegen/llvm.zig+9-1
...@@ -5149,6 +5149,11 @@ pub const FuncGen = struct {...@@ -5149,6 +5149,11 @@ pub const FuncGen = struct {
5149 const same_size_int = self.context.intType(elem_bits);5149 const same_size_int = self.context.intType(elem_bits);
5150 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");5150 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
5151 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");5151 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");
5152 } else if (field_ty.zigTypeTag() == .Pointer) {
5153 const elem_bits = @intCast(c_uint, field_ty.bitSize(target));
5154 const same_size_int = self.context.intType(elem_bits);
5155 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
5156 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");
5152 }5157 }
5153 return self.builder.buildTrunc(shifted_value, elem_llvm_ty, "");5158 return self.builder.buildTrunc(shifted_value, elem_llvm_ty, "");
5154 },5159 },
...@@ -7999,7 +8004,10 @@ pub const FuncGen = struct {...@@ -7999,7 +8004,10 @@ pub const FuncGen = struct {
7999 const non_int_val = try self.resolveInst(elem);8004 const non_int_val = try self.resolveInst(elem);
8000 const ty_bit_size = @intCast(u16, field.ty.bitSize(target));8005 const ty_bit_size = @intCast(u16, field.ty.bitSize(target));
8001 const small_int_ty = self.dg.context.intType(ty_bit_size);8006 const small_int_ty = self.dg.context.intType(ty_bit_size);
8002 const small_int_val = self.builder.buildBitCast(non_int_val, small_int_ty, "");8007 const small_int_val = if (field.ty.zigTypeTag() == .Pointer)
8008 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")
8009 else
8010 self.builder.buildBitCast(non_int_val, small_int_ty, "");
8003 const shift_rhs = int_llvm_ty.constInt(running_bits, .False);8011 const shift_rhs = int_llvm_ty.constInt(running_bits, .False);
8004 // If the field is as large as the entire packed struct, this8012 // If the field is as large as the entire packed struct, this
8005 // zext would go from, e.g. i16 to i16. This is legal with8013 // zext would go from, e.g. i16 to i16. This is legal with
test/behavior/packed-struct.zig+21
...@@ -413,3 +413,24 @@ test "byte-aligned field pointer offsets" {...@@ -413,3 +413,24 @@ test "byte-aligned field pointer offsets" {
413 try S.doTheTest();413 try S.doTheTest();
414 comptime try S.doTheTest();414 comptime try S.doTheTest();
415}415}
416
417test "load pointer from packed struct" {
418 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
419 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
420 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
421 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
422 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
423
424 const Symbol = struct {
425 index: u16,
426 };
427 const Relocation = packed struct {
428 symbol: *Symbol,
429 a: u32,
430 };
431 var a: []Relocation = &.{};
432 for (a) |rela| {
433 var b = rela.symbol.index;
434 _ = b;
435 }
436}