Skip to content

Commit 7ec43b2

Browse files
committed
llvm: truncate non ABI sized integers on load
Closes ziglang#11263 Closes ziglang#13480
1 parent a2b5c24 commit 7ec43b2

File tree

4 files changed

+55
-1
lines changed

4 files changed

+55
-1
lines changed

src/codegen/llvm.zig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9699,6 +9699,15 @@ pub const FuncGen = struct {
96999699
if (isByRef(info.pointee_type)) {
97009700
return self.loadByRef(ptr, info.pointee_type, ptr_alignment, info.@"volatile");
97019701
}
9702+
if (info.pointee_type.isAbiInt()) {
9703+
const abi_size_bits = info.pointee_type.abiSize(target) * 8;
9704+
const abi_int_ty = self.dg.context.intType(@intCast(c_uint, abi_size_bits));
9705+
const llvm_inst = self.builder.buildLoad(abi_int_ty, ptr, "");
9706+
llvm_inst.setAlignment(ptr_alignment);
9707+
llvm_inst.setVolatile(ptr_volatile);
9708+
const elem_llvm_ty = try self.dg.lowerType(info.pointee_type);
9709+
return self.builder.buildTrunc(llvm_inst, elem_llvm_ty, "");
9710+
}
97029711
const elem_llvm_ty = try self.dg.lowerType(info.pointee_type);
97039712
const llvm_inst = self.builder.buildLoad(elem_llvm_ty, ptr, "");
97049713
llvm_inst.setAlignment(ptr_alignment);

src/type.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4560,7 +4560,7 @@ pub const Type = extern union {
45604560
pub fn isAbiInt(ty: Type) bool {
45614561
return switch (ty.zigTypeTag()) {
45624562
.Int, .Enum, .ErrorSet => true,
4563-
.Struct => ty.containerLayout() == .Packed,
4563+
.Struct, .Union => ty.containerLayout() == .Packed,
45644564
else => false,
45654565
};
45664566
}

test/behavior.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ test {
116116
_ = @import("behavior/bugs/13171.zig");
117117
_ = @import("behavior/bugs/13285.zig");
118118
_ = @import("behavior/bugs/13435.zig");
119+
_ = @import("behavior/bugs/13480.zig");
119120
_ = @import("behavior/byteswap.zig");
120121
_ = @import("behavior/byval_arg_var.zig");
121122
_ = @import("behavior/call.zig");

test/behavior/bugs/13480.zig

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
const builtin = @import("builtin");
2+
const std = @import("std");
3+
const expect = std.testing.expect;
4+
5+
const BitSet = packed struct {
6+
mask: u7,
7+
};
8+
9+
const Display = struct {
10+
// This array has to be large. Using separate padding
11+
// plus a one item array doesn't work.
12+
digit_masks: [10]BitSet = undefined,
13+
};
14+
15+
fn smash() void {
16+
var stack: [0x500]u8 = undefined;
17+
@memset(&stack, 0xFF, stack.len);
18+
}
19+
20+
fn stackUp(display: Display) !void {
21+
var space: [0x100]u8 = undefined;
22+
try part2(display);
23+
_ = space;
24+
}
25+
26+
fn part2(display: Display) !void {
27+
var mask_a = BitSet{
28+
.mask = display.digit_masks[9].mask,
29+
};
30+
try expect(mask_a.mask == 0b0001000);
31+
}
32+
33+
test {
34+
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
35+
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
36+
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
37+
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
38+
39+
var display = Display{};
40+
display.digit_masks[9] = .{ .mask = 0b0001000 };
41+
42+
smash();
43+
try stackUp(display);
44+
}

0 commit comments

Comments
 (0)