authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-11-24 10:14:16+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-11-25 16:36:57-07:00
log24d4bfb666cff9617687c1d5a2b22395c51a000e
tree84c2852b38464bff57b56bcef297e57d67f29a6b
parent06a75c16ffb8a5e5a7a1d6af3f398a5ff4959df3

stage1: Fix ICE when generating struct fields with padding

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 #5398

3 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_
70187018 LLVMConstNull(get_llvm_type(g, u32)),
70197019 LLVMConstInt(get_llvm_type(g, u32), field_index, false),
70207020 };
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);
70227029}
70237030
70247031static 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 {
5050 _ = @import("behavior/bugs/4769_b.zig");
5151 _ = @import("behavior/bugs/4769_c.zig");
5252 _ = @import("behavior/bugs/4954.zig");
53 _ = @import("behavior/bugs/5398.zig");
5354 _ = @import("behavior/bugs/5413.zig");
5455 _ = @import("behavior/bugs/5474.zig");
5556 _ = @import("behavior/bugs/5487.zig");
test/stage1/behavior/bugs/5398.zig created+31
......@@ -0,0 +1,31 @@
1const std = @import("std");
2const testing = std.testing;
3
4pub const Mesh = struct {
5 id: u32,
6};
7pub const Material = struct {
8 transparent: bool = true,
9 emits_shadows: bool = true,
10 render_color: bool = true,
11};
12pub const Renderable = struct {
13 material: Material,
14 // The compiler inserts some padding here to ensure Mesh is correctly aligned.
15 mesh: Mesh,
16};
17
18var renderable: Renderable = undefined;
19
20test "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}