From 0570df69b178c99f4d9d679a57d966f507dda484 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 13 Oct 2020 19:34:20 +0200 Subject: [PATCH] stage1: Fix missing runtime safety check for intToPtr Elide the alignment check if the pointer alignment is one, the null check must be preserved as it depends on the pointer type. Fixes #6667 --- src/stage1/codegen.cpp | 4 ++-- test/runtime_safety.zig | 26 ++++++++++++++++++-------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp index 9ed2ba9d7392e9e791b8daf1ab9aaf00987e31c2..5e9b84d25ae1b1036ac49bfd8075e7b4a2b3812a 100644 --- a/src/stage1/codegen.cpp +++ b/src/stage1/codegen.cpp @@ -3379,7 +3379,7 @@ static LLVMValueRef ir_render_int_to_ptr(CodeGen *g, IrExecutableGen *executable LLVMValueRef target_val = ir_llvm_value(g, instruction->target); const uint32_t align_bytes = get_ptr_align(g, wanted_type); - if (ir_want_runtime_safety(g, &instruction->base) && align_bytes > 1) { + if (ir_want_runtime_safety(g, &instruction->base)) { ZigType *usize = g->builtin_types.entry_usize; LLVMValueRef zero = LLVMConstNull(usize->llvm_type); @@ -3395,7 +3395,7 @@ static LLVMValueRef ir_render_int_to_ptr(CodeGen *g, IrExecutableGen *executable LLVMPositionBuilderAtEnd(g->builder, ok_block); } - { + if (align_bytes > 1) { LLVMValueRef alignment_minus_1 = LLVMConstInt(usize->llvm_type, align_bytes - 1, false); LLVMValueRef anded_val = LLVMBuildAnd(g->builder, target_val, alignment_minus_1, ""); LLVMValueRef is_ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, anded_val, zero, ""); diff --git a/test/runtime_safety.zig b/test/runtime_safety.zig index e27ae7e16ecf16140d70258520b7af64b11115b4..8d962b088e362f92004b213476629a0e611260ee 100644 --- a/test/runtime_safety.zig +++ b/test/runtime_safety.zig @@ -13,7 +13,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { cases.addRuntimeSafety("slicing operator with sentinel", \\const std = @import("std"); - ++ check_panic_msg ++ + ++ check_panic_msg ++ \\pub fn main() void { \\ var buf = [4]u8{'a','b','c',0}; \\ const slice = buf[0..4 :0]; @@ -21,7 +21,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { ); cases.addRuntimeSafety("slicing operator with sentinel", \\const std = @import("std"); - ++ check_panic_msg ++ + ++ check_panic_msg ++ \\pub fn main() void { \\ var buf = [4]u8{'a','b','c',0}; \\ const slice = buf[0..:0]; @@ -29,7 +29,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { ); cases.addRuntimeSafety("slicing operator with sentinel", \\const std = @import("std"); - ++ check_panic_msg ++ + ++ check_panic_msg ++ \\pub fn main() void { \\ var buf_zero = [0]u8{}; \\ const slice = buf_zero[0..0 :0]; @@ -37,7 +37,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { ); cases.addRuntimeSafety("slicing operator with sentinel", \\const std = @import("std"); - ++ check_panic_msg ++ + ++ check_panic_msg ++ \\pub fn main() void { \\ var buf_zero = [0]u8{}; \\ const slice = buf_zero[0..:0]; @@ -45,7 +45,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { ); cases.addRuntimeSafety("slicing operator with sentinel", \\const std = @import("std"); - ++ check_panic_msg ++ + ++ check_panic_msg ++ \\pub fn main() void { \\ var buf_sentinel = [2:0]u8{'a','b'}; \\ @ptrCast(*[3]u8, &buf_sentinel)[2] = 0; @@ -54,7 +54,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { ); cases.addRuntimeSafety("slicing operator with sentinel", \\const std = @import("std"); - ++ check_panic_msg ++ + ++ check_panic_msg ++ \\pub fn main() void { \\ var buf_slice: []const u8 = &[3]u8{ 'a', 'b', 0 }; \\ const slice = buf_slice[0..3 :0]; @@ -62,7 +62,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { ); cases.addRuntimeSafety("slicing operator with sentinel", \\const std = @import("std"); - ++ check_panic_msg ++ + ++ check_panic_msg ++ \\pub fn main() void { \\ var buf_slice: []const u8 = &[3]u8{ 'a', 'b', 0 }; \\ const slice = buf_slice[0.. :0]; @@ -354,7 +354,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { \\} ); - cases.addRuntimeSafety("@ptrToInt address zero to non-optional pointer", + cases.addRuntimeSafety("@intToPtr address zero to non-optional pointer", \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ @import("std").os.exit(126); \\} @@ -364,6 +364,16 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { \\} ); + cases.addRuntimeSafety("@intToPtr address zero to non-optional byte-aligned pointer", + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { + \\ @import("std").os.exit(126); + \\} + \\pub fn main() void { + \\ var zero: usize = 0; + \\ var b = @intToPtr(*u8, zero); + \\} + ); + cases.addRuntimeSafety("pointer casting null to non-optional pointer", \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ @import("std").os.exit(126); -- 2.54.0