fix safety for sentinel-slicing floats

This commit is contained in:
Andrew Kelley 2019-12-20 18:19:01 -05:00
parent 8918cb06fc
commit 8d73703d52
No known key found for this signature in database
GPG key ID: 7C5F548F728501A9
2 changed files with 34 additions and 1 deletions

View file

@ -1425,7 +1425,12 @@ static void add_sentinel_check(CodeGen *g, LLVMValueRef sentinel_elem_ptr, ZigVa
LLVMValueRef expected_sentinel = gen_const_val(g, sentinel, ""); LLVMValueRef expected_sentinel = gen_const_val(g, sentinel, "");
LLVMValueRef actual_sentinel = gen_load_untyped(g, sentinel_elem_ptr, 0, false, ""); LLVMValueRef actual_sentinel = gen_load_untyped(g, sentinel_elem_ptr, 0, false, "");
LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, actual_sentinel, expected_sentinel, ""); LLVMValueRef ok_bit;
if (sentinel->type->id == ZigTypeIdFloat) {
ok_bit = LLVMBuildFCmp(g->builder, LLVMRealOEQ, actual_sentinel, expected_sentinel, "");
} else {
ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, actual_sentinel, expected_sentinel, "");
}
LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "SentinelFail"); LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "SentinelFail");
LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "SentinelOk"); LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "SentinelOk");

View file

@ -1,6 +1,34 @@
const tests = @import("tests.zig"); const tests = @import("tests.zig");
pub fn addCases(cases: *tests.CompareOutputContext) void { pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("slice sentinel mismatch - optional pointers",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ if (std.mem.eql(u8, message, "sentinel mismatch")) {
\\ std.process.exit(126); // good
\\ }
\\ std.process.exit(0); // test failed
\\}
\\pub fn main() void {
\\ var buf: [4]?*i32 = undefined;
\\ const slice = buf[0..3 :null];
\\}
);
cases.addRuntimeSafety("slice sentinel mismatch - floats",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ if (std.mem.eql(u8, message, "sentinel mismatch")) {
\\ std.process.exit(126); // good
\\ }
\\ std.process.exit(0); // test failed
\\}
\\pub fn main() void {
\\ var buf: [4]f32 = undefined;
\\ const slice = buf[0..3 :1.2];
\\}
);
cases.addRuntimeSafety("pointer slice sentinel mismatch", cases.addRuntimeSafety("pointer slice sentinel mismatch",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {