From bfe3317059131ab552f7583b88d6bc82609d198c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?fn=20=E2=8C=83=20=E2=8C=A5?= <70830482+FnControlOption@users.noreply.github.com> Date: Wed, 16 Apr 2025 11:59:47 -0700 Subject: [PATCH] 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` --- src/Type.zig | 23 ++++++++++++------ test/behavior/abs.zig | 54 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 7 deletions(-) diff --git a/src/Type.zig b/src/Type.zig index 3c13f3db94..5577d82335 100644 --- a/src/Type.zig +++ b/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, + }, }; } diff --git a/test/behavior/abs.zig b/test/behavior/abs.zig index 078362cf3e..1b12e08ecc 100644 --- a/test/behavior/abs.zig +++ b/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