From 26265e29f4599660a4bfcbc196fc98110bdac6d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Tue, 13 Oct 2026 20:06:22 +0200 Subject: [PATCH] std.c, libzigc: fix ffs() family signatures and implementation bugs --- lib/c/strings.zig | 8 ++++---- lib/std/c.zig | 4 ++-- test/c/strings.zig | 8 ++------ 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/lib/c/strings.zig b/lib/c/strings.zig index 111da9ad0f04eff48c890c6b33b5481c733a8aae..11643e066a12da636297f4a1e63c8f7fd48c3365 100644 --- a/lib/c/strings.zig +++ b/lib/c/strings.zig @@ -44,19 +44,19 @@ fn rindex(str: [*:0]const c_char, value: c_int) callconv(.c) ?[*:0]c_char { return @constCast(str[std.mem.findScalarLast(u8, std.mem.span(@as([*:0]const u8, @ptrCast(str))), @truncate(@as(c_uint, @bitCast(value)))) orelse return null ..]); } -fn firstBitSet(comptime T: type, value: T) T { - return @bitSizeOf(T) - @clz(value); +fn firstBitSet(comptime T: type, value: T) c_int { + return if (value == 0) 0 else @as(c_int, @ctz(value)) + 1; } fn ffs(i: c_int) callconv(.c) c_int { return firstBitSet(c_int, i); } -fn ffsl(i: c_long) callconv(.c) c_long { +fn ffsl(i: c_long) callconv(.c) c_int { return firstBitSet(c_long, i); } -fn ffsll(i: c_longlong) callconv(.c) c_longlong { +fn ffsll(i: c_longlong) callconv(.c) c_int { return firstBitSet(c_longlong, i); } diff --git a/lib/std/c.zig b/lib/std/c.zig index 3bffe16ea78947721e7c4d9d39280d2b0d6ce37e..69c29af84368b22df157932076f46198545e88f9 100644 --- a/lib/std/c.zig +++ b/lib/std/c.zig @@ -11579,8 +11579,8 @@ pub const wcsdup = switch (builtin.abi) { }; pub extern "c" fn ffs(i: c_int) c_int; -pub extern "c" fn ffsl(i: c_long) c_long; -pub extern "c" fn ffsll(i: c_longlong) c_longlong; +pub extern "c" fn ffsl(i: c_long) c_int; +pub extern "c" fn ffsll(i: c_longlong) c_int; pub extern "c" fn erand48(xsubi: *[3]c_ushort) f64; pub extern "c" fn jrand48(xsubi: *[3]c_ushort) c_long; diff --git a/test/c/strings.zig b/test/c/strings.zig index baea1a8fe1f658dbd4c6a9491b4c14d57d22b842..c7f180d0540ac7960e156bb047ac05e7ab34a30d 100644 --- a/test/c/strings.zig +++ b/test/c/strings.zig @@ -26,9 +26,8 @@ fn testFfs(comptime T: type) !void { try testing.expectEqual(0, ffs(0)); for (0..@bitSizeOf(T)) |i| { - const bit = @as(T, 1) << @intCast(i); - - try testing.expectEqual(@as(T, @intCast(i + 1)), ffs(bit)); + try testing.expectEqual(@as(c_int, @intCast(i + 1)), ffs(@as(T, 1) << @intCast(i))); + try testing.expectEqual(@as(c_int, @intCast(i + 1)), ffs(@as(T, -1) << @intCast(i))); } } @@ -41,9 +40,6 @@ test "ffs" { if (builtin.target.os.tag == .netbsd) return; // no ffsl/ffsll until 11 try testFfs(c_long); - - if (@sizeOf(usize) == 4) return error.SkipZigTest; // TODO - try testFfs(c_longlong); } -- 2.54.0