authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-10-27 13:37:46-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-10-27 22:11:20-04:00
log1f4f8d34a1e607a1189280cc0f809c851431a520
treeca9f4a19c74da6a77a5f976dbaf41feb4f62bb29
parent2991e4a454c4d719226fcfc7e8ac8dec44250a7e

compiler_rt: fix memcmp wrong for some inputs

See the new test case - this fails in the previous implementation. See #13303

1 files changed, 13 insertions(+), 14 deletions(-)

lib/compiler_rt/memcmp.zig+13-14
......@@ -5,27 +5,26 @@ comptime {
55 @export(memcmp, .{ .name = "memcmp", .linkage = common.linkage });
66}
77
8pub fn memcmp(vl: ?[*]const u8, vr: ?[*]const u8, n: usize) callconv(.C) c_int {
9 @setRuntimeSafety(false);
10
11 var index: usize = 0;
12 while (index != n) : (index += 1) {
13 const compare_val = @bitCast(i8, vl.?[index] -% vr.?[index]);
14 if (compare_val != 0) {
15 return compare_val;
16 }
8pub fn memcmp(vl: [*]const u8, vr: [*]const u8, n: usize) callconv(.C) c_int {
9 var i: usize = 0;
10 while (i < n) : (i += 1) {
11 const compared = @as(c_int, vl[i]) -% @as(c_int, vr[i]);
12 if (compared != 0) return compared;
1713 }
18
1914 return 0;
2015}
2116
2217test "memcmp" {
23 const base_arr = &[_]u8{ 1, 1, 1 };
18 const arr0 = &[_]u8{ 1, 1, 1 };
2419 const arr1 = &[_]u8{ 1, 1, 1 };
2520 const arr2 = &[_]u8{ 1, 0, 1 };
2621 const arr3 = &[_]u8{ 1, 2, 1 };
22 const arr4 = &[_]u8{ 1, 0xff, 1 };
23
24 try std.testing.expect(memcmp(arr0, arr1, 3) == 0);
25 try std.testing.expect(memcmp(arr0, arr2, 3) > 0);
26 try std.testing.expect(memcmp(arr0, arr3, 3) < 0);
2727
28 try std.testing.expect(memcmp(base_arr[0..], arr1[0..], base_arr.len) == 0);
29 try std.testing.expect(memcmp(base_arr[0..], arr2[0..], base_arr.len) > 0);
30 try std.testing.expect(memcmp(base_arr[0..], arr3[0..], base_arr.len) < 0);
28 try std.testing.expect(memcmp(arr0, arr4, 3) < 0);
29 try std.testing.expect(memcmp(arr4, arr0, 3) > 0);
3130}