mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 14:25:16 +00:00
Add mask before truncating dereferenced bit pointers (#9584)
This commit is contained in:
parent
4c9d41730e
commit
5cd1d42a35
@ -3831,10 +3831,14 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, Stage1Air *executable,
|
||||
LLVMValueRef shift_amt_val = LLVMConstInt(LLVMTypeOf(containing_int), shift_amt, false);
|
||||
LLVMValueRef shifted_value = LLVMBuildLShr(g->builder, containing_int, shift_amt_val, "");
|
||||
|
||||
LLVMTypeRef same_size_int = LLVMIntType(size_in_bits);
|
||||
LLVMValueRef mask = LLVMConstAllOnes(LLVMIntType(size_in_bits));
|
||||
mask = LLVMConstZExt(mask, LLVMTypeOf(containing_int));
|
||||
LLVMValueRef masked_value = LLVMBuildAnd(g->builder, shifted_value, mask, "");
|
||||
|
||||
if (handle_is_ptr(g, child_type)) {
|
||||
LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
|
||||
LLVMTypeRef same_size_int = LLVMIntType(size_in_bits);
|
||||
LLVMValueRef truncated_int = LLVMBuildTrunc(g->builder, shifted_value, same_size_int, "");
|
||||
LLVMValueRef truncated_int = LLVMBuildTrunc(g->builder, masked_value, same_size_int, "");
|
||||
LLVMValueRef bitcasted_ptr = LLVMBuildBitCast(g->builder, result_loc,
|
||||
LLVMPointerType(same_size_int, 0), "");
|
||||
LLVMBuildStore(g->builder, truncated_int, bitcasted_ptr);
|
||||
@ -3842,12 +3846,11 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, Stage1Air *executable,
|
||||
}
|
||||
|
||||
if (child_type->id == ZigTypeIdFloat) {
|
||||
LLVMTypeRef same_size_int = LLVMIntType(size_in_bits);
|
||||
LLVMValueRef truncated_int = LLVMBuildTrunc(g->builder, shifted_value, same_size_int, "");
|
||||
LLVMValueRef truncated_int = LLVMBuildTrunc(g->builder, masked_value, same_size_int, "");
|
||||
return LLVMBuildBitCast(g->builder, truncated_int, get_llvm_type(g, child_type), "");
|
||||
}
|
||||
|
||||
return LLVMBuildTrunc(g->builder, shifted_value, get_llvm_type(g, child_type), "");
|
||||
return LLVMBuildTrunc(g->builder, masked_value, get_llvm_type(g, child_type), "");
|
||||
}
|
||||
|
||||
static bool value_is_all_undef_array(CodeGen *g, ZigValue *const_val, size_t len) {
|
||||
|
||||
@ -71,6 +71,7 @@ test {
|
||||
_ = @import("behavior/bugs/7047.zig");
|
||||
_ = @import("behavior/bugs/7003.zig");
|
||||
_ = @import("behavior/bugs/7250.zig");
|
||||
_ = @import("behavior/bugs/9584.zig");
|
||||
_ = @import("behavior/bugs/394.zig");
|
||||
_ = @import("behavior/bugs/421.zig");
|
||||
_ = @import("behavior/bugs/529.zig");
|
||||
|
||||
60
test/behavior/bugs/9584.zig
Normal file
60
test/behavior/bugs/9584.zig
Normal file
@ -0,0 +1,60 @@
|
||||
const std = @import("std");
|
||||
|
||||
const A = packed struct {
|
||||
a: bool,
|
||||
b: bool,
|
||||
c: bool,
|
||||
d: bool,
|
||||
|
||||
e: bool,
|
||||
f: bool,
|
||||
g: bool,
|
||||
h: bool,
|
||||
};
|
||||
|
||||
const X = union {
|
||||
x: A,
|
||||
y: u64,
|
||||
};
|
||||
|
||||
pub fn a(
|
||||
x0: i32,
|
||||
x1: i32,
|
||||
x2: i32,
|
||||
x3: i32,
|
||||
x4: i32,
|
||||
flag_a: bool,
|
||||
flag_b: bool,
|
||||
) !void {
|
||||
_ = x0;
|
||||
_ = x1;
|
||||
_ = x2;
|
||||
_ = x3;
|
||||
_ = x4;
|
||||
_ = flag_a;
|
||||
// With this bug present, `flag_b` would actually contain the value 17.
|
||||
// Note: this bug only presents itself on debug mode.
|
||||
try std.testing.expect(@ptrCast(*const u8, &flag_b).* == 1);
|
||||
}
|
||||
|
||||
pub fn b(x: *X) !void {
|
||||
try a(0, 1, 2, 3, 4, x.x.a, x.x.b);
|
||||
}
|
||||
|
||||
test "bug 9584" {
|
||||
var flags = A{
|
||||
.a = false,
|
||||
.b = true,
|
||||
.c = false,
|
||||
.d = false,
|
||||
|
||||
.e = false,
|
||||
.f = true,
|
||||
.g = false,
|
||||
.h = false,
|
||||
};
|
||||
var x = X{
|
||||
.x = flags,
|
||||
};
|
||||
try b(&x);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user