Commit bfe3317059

fn ⌃ ⌥ <70830482+FnControlOption@users.noreply.github.com>
2025-04-16 20:59:47
Return a `usize` from `@abs` if given an `isize`
Also: - `c_ushort` for `c_short` - `c_uint` for `c_int` - `c_ulong` for `c_long` - `c_ulonglong` for `c_longlong`
1 parent 44e99ed
Changed files (2)
src
test
behavior
src/Type.zig
@@ -3445,13 +3445,22 @@ pub fn optEuBaseType(ty: Type, zcu: *const Zcu) Type {
 
 pub fn toUnsigned(ty: Type, pt: Zcu.PerThread) !Type {
     const zcu = pt.zcu;
-    return switch (ty.zigTypeTag(zcu)) {
-        .int => pt.intType(.unsigned, ty.intInfo(zcu).bits),
-        .vector => try pt.vectorType(.{
-            .len = ty.vectorLen(zcu),
-            .child = (try ty.childType(zcu).toUnsigned(pt)).toIntern(),
-        }),
-        else => unreachable,
+    return switch (ty.toIntern()) {
+        // zig fmt: off
+        .usize_type,       .isize_type      => .usize,
+        .c_ushort_type,    .c_short_type    => .c_ushort,
+        .c_uint_type,      .c_int_type      => .c_uint,
+        .c_ulong_type,     .c_long_type     => .c_ulong,
+        .c_ulonglong_type, .c_longlong_type => .c_ulonglong,
+        // zig fmt: on
+        else => switch (ty.zigTypeTag(zcu)) {
+            .int => pt.intType(.unsigned, ty.intInfo(zcu).bits),
+            .vector => try pt.vectorType(.{
+                .len = ty.vectorLen(zcu),
+                .child = (try ty.childType(zcu).toUnsigned(pt)).toIntern(),
+            }),
+            else => unreachable,
+        },
     };
 }
 
test/behavior/abs.zig
@@ -1,5 +1,6 @@
 const builtin = @import("builtin");
 const std = @import("std");
+const assert = std.debug.assert;
 const expect = std.testing.expect;
 
 test "@abs integers" {
@@ -48,6 +49,33 @@ fn testAbsIntegers() !void {
     }
 }
 
+test "@abs signed C ABI integers" {
+    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
+
+    const S = struct {
+        fn doTheTest() !void {
+            try testOne(isize, usize);
+            try testOne(c_short, c_ushort);
+            try testOne(c_int, c_uint);
+            try testOne(c_long, c_ulong);
+            if (!builtin.cpu.arch.isSpirV()) try testOne(c_longlong, c_ulonglong);
+        }
+        fn testOne(comptime Signed: type, comptime Unsigned: type) !void {
+            var negative_one: Signed = undefined;
+            negative_one = -1;
+            const one = @abs(negative_one);
+            comptime assert(@TypeOf(one) == Unsigned);
+            try expect(one == 1);
+        }
+    };
+
+    try S.doTheTest();
+    try comptime S.doTheTest();
+}
+
 test "@abs unsigned integers" {
     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
@@ -87,6 +115,32 @@ fn testAbsUnsignedIntegers() !void {
     }
 }
 
+test "@abs unsigned C ABI integers" {
+    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
+
+    const S = struct {
+        fn doTheTest() !void {
+            try testOne(usize);
+            try testOne(c_ushort);
+            try testOne(c_uint);
+            try testOne(c_ulong);
+            if (!builtin.cpu.arch.isSpirV()) try testOne(c_ulonglong);
+        }
+        fn testOne(comptime Unsigned: type) !void {
+            var one: Unsigned = undefined;
+            one = 1;
+            const still_one = @abs(one);
+            comptime assert(@TypeOf(still_one) == Unsigned);
+            try expect(still_one == 1);
+        }
+    };
+
+    try S.doTheTest();
+    try comptime S.doTheTest();
+}
+
 test "@abs big int <= 128 bits" {
     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO