Commit 1f4f8d34a1

Andrew Kelley <andrew@ziglang.org>
2022-10-27 22:37:46
compiler_rt: fix memcmp wrong for some inputs
See the new test case - this fails in the previous implementation. See #13303
1 parent 2991e4a
Changed files (1)
lib
compiler_rt
lib/compiler_rt/memcmp.zig
@@ -5,27 +5,26 @@ comptime {
     @export(memcmp, .{ .name = "memcmp", .linkage = common.linkage });
 }
 
-pub fn memcmp(vl: ?[*]const u8, vr: ?[*]const u8, n: usize) callconv(.C) c_int {
-    @setRuntimeSafety(false);
-
-    var index: usize = 0;
-    while (index != n) : (index += 1) {
-        const compare_val = @bitCast(i8, vl.?[index] -% vr.?[index]);
-        if (compare_val != 0) {
-            return compare_val;
-        }
+pub fn memcmp(vl: [*]const u8, vr: [*]const u8, n: usize) callconv(.C) c_int {
+    var i: usize = 0;
+    while (i < n) : (i += 1) {
+        const compared = @as(c_int, vl[i]) -% @as(c_int, vr[i]);
+        if (compared != 0) return compared;
     }
-
     return 0;
 }
 
 test "memcmp" {
-    const base_arr = &[_]u8{ 1, 1, 1 };
+    const arr0 = &[_]u8{ 1, 1, 1 };
     const arr1 = &[_]u8{ 1, 1, 1 };
     const arr2 = &[_]u8{ 1, 0, 1 };
     const arr3 = &[_]u8{ 1, 2, 1 };
+    const arr4 = &[_]u8{ 1, 0xff, 1 };
+
+    try std.testing.expect(memcmp(arr0, arr1, 3) == 0);
+    try std.testing.expect(memcmp(arr0, arr2, 3) > 0);
+    try std.testing.expect(memcmp(arr0, arr3, 3) < 0);
 
-    try std.testing.expect(memcmp(base_arr[0..], arr1[0..], base_arr.len) == 0);
-    try std.testing.expect(memcmp(base_arr[0..], arr2[0..], base_arr.len) > 0);
-    try std.testing.expect(memcmp(base_arr[0..], arr3[0..], base_arr.len) < 0);
+    try std.testing.expect(memcmp(arr0, arr4, 3) < 0);
+    try std.testing.expect(memcmp(arr4, arr0, 3) > 0);
 }