| author | |
| committer | |
| log | 24d4bfb666cff9617687c1d5a2b22395c51a000e |
| tree | 84c2852b38464bff57b56bcef297e57d67f29a6b |
| parent | 06a75c16ffb8a5e5a7a1d6af3f398a5ff4959df3 |
Make gen_const_ptr_struct_recursive aware of the possible presence of
some trailing padding by always bitcasting the pointer to its expected
type.
Not an elegant solution but makes LLVM happy and is consistent with how
the other callsites are handling this case.
Fixes #53983 files changed, 40 insertions(+), 1 deletions(-)
src/stage1/codegen.cpp+8-1| ... | @@ -7018,7 +7018,14 @@ static LLVMValueRef gen_const_ptr_struct_recursive(CodeGen *g, ZigValue *struct_ | ... | @@ -7018,7 +7018,14 @@ static LLVMValueRef gen_const_ptr_struct_recursive(CodeGen *g, ZigValue *struct_ |
| 7018 | LLVMConstNull(get_llvm_type(g, u32)), | 7018 | LLVMConstNull(get_llvm_type(g, u32)), |
| 7019 | LLVMConstInt(get_llvm_type(g, u32), field_index, false), | 7019 | LLVMConstInt(get_llvm_type(g, u32), field_index, false), |
| 7020 | }; | 7020 | }; |
| 7021 | return LLVMConstInBoundsGEP(base_ptr, indices, 2); | 7021 | |
| 7022 | // The structure pointed by base_ptr may include trailing padding for | ||
| 7023 | // alignment purposes and have the following LLVM type: <{ %T, [N x i8] }>. | ||
| 7024 | // Add an extra bitcast as we're only interested in the %T part. | ||
| 7025 | assert(handle_is_ptr(g, struct_const_val->type)); | ||
| 7026 | LLVMValueRef casted_base_ptr = LLVMConstBitCast(base_ptr, | ||
| 7027 | LLVMPointerType(get_llvm_type(g, struct_const_val->type), 0)); | ||
| 7028 | return LLVMConstInBoundsGEP(casted_base_ptr, indices, 2); | ||
| 7022 | } | 7029 | } |
| 7023 | 7030 | ||
| 7024 | static LLVMValueRef gen_const_ptr_err_union_code_recursive(CodeGen *g, ZigValue *err_union_const_val) { | 7031 | static LLVMValueRef gen_const_ptr_err_union_code_recursive(CodeGen *g, ZigValue *err_union_const_val) { |
test/stage1/behavior.zig+1| ... | @@ -50,6 +50,7 @@ comptime { | ... | @@ -50,6 +50,7 @@ comptime { |
| 50 | _ = @import("behavior/bugs/4769_b.zig"); | 50 | _ = @import("behavior/bugs/4769_b.zig"); |
| 51 | _ = @import("behavior/bugs/4769_c.zig"); | 51 | _ = @import("behavior/bugs/4769_c.zig"); |
| 52 | _ = @import("behavior/bugs/4954.zig"); | 52 | _ = @import("behavior/bugs/4954.zig"); |
| 53 | _ = @import("behavior/bugs/5398.zig"); | ||
| 53 | _ = @import("behavior/bugs/5413.zig"); | 54 | _ = @import("behavior/bugs/5413.zig"); |
| 54 | _ = @import("behavior/bugs/5474.zig"); | 55 | _ = @import("behavior/bugs/5474.zig"); |
| 55 | _ = @import("behavior/bugs/5487.zig"); | 56 | _ = @import("behavior/bugs/5487.zig"); |
test/stage1/behavior/bugs/5398.zig created+31| ... | @@ -0,0 +1,31 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const testing = std.testing; | ||
| 3 | |||
| 4 | pub const Mesh = struct { | ||
| 5 | id: u32, | ||
| 6 | }; | ||
| 7 | pub const Material = struct { | ||
| 8 | transparent: bool = true, | ||
| 9 | emits_shadows: bool = true, | ||
| 10 | render_color: bool = true, | ||
| 11 | }; | ||
| 12 | pub const Renderable = struct { | ||
| 13 | material: Material, | ||
| 14 | // The compiler inserts some padding here to ensure Mesh is correctly aligned. | ||
| 15 | mesh: Mesh, | ||
| 16 | }; | ||
| 17 | |||
| 18 | var renderable: Renderable = undefined; | ||
| 19 | |||
| 20 | test "assignment of field with padding" { | ||
| 21 | renderable = Renderable{ | ||
| 22 | .mesh = Mesh{ .id = 0 }, | ||
| 23 | .material = Material{ | ||
| 24 | .transparent = false, | ||
| 25 | .emits_shadows = false, | ||
| 26 | }, | ||
| 27 | }; | ||
| 28 | testing.expectEqual(false, renderable.material.transparent); | ||
| 29 | testing.expectEqual(false, renderable.material.emits_shadows); | ||
| 30 | testing.expectEqual(true, renderable.material.render_color); | ||
| 31 | } | ||