authorgravatar for evan@lagerdata.comEvan Haas <evan@lagerdata.com> 2023-06-20 00:20:32-07:00
committergravatar for evan@lagerdata.comEvan Haas <evan@lagerdata.com> 2023-06-20 00:26:42-07:00
logfb9d6b8bd96b1d0403f04fd31b1ebc0881105f48
tree740adc7995bd1395bc53b5446adc444d42b57bb9
parent657fe557115d9fde5de5b8c6b65a4db4e3a2e567
signaturebadge-check Signed by SSH key SHA256:cf2/TFgSxv2uRX26INvFSw25Prr1Dy9H8MiRXgLpok4

codegen: Set c_char signedness based on the target


5 files changed, 18 insertions(+), 5 deletions(-)

src/codegen/c.zig+1-1
......@@ -1880,7 +1880,7 @@ pub const DeclGen = struct {
18801880 if (cty.isBool())
18811881 signAbbrev(.unsigned)
18821882 else if (cty.isInteger())
1883 signAbbrev(cty.signedness() orelse .unsigned)
1883 signAbbrev(cty.signedness(dg.module.getTarget()))
18841884 else if (cty.isFloat())
18851885 @as(u8, 'f')
18861886 else if (cty.isPointer())
src/codegen/c/type.zig+2-2
......@@ -537,9 +537,9 @@ pub const CType = extern union {
537537 };
538538 }
539539
540 pub fn signedness(self: CType) ?std.builtin.Signedness {
540 pub fn signedness(self: CType, target: std.Target) std.builtin.Signedness {
541541 return switch (self.tag()) {
542 .char => null, // unknown signedness
542 .char => target.charSignedness(),
543543 .@"signed char",
544544 .short,
545545 .int,
src/type.zig+4-2
......@@ -2216,7 +2216,8 @@ pub const Type = struct {
22162216 /// Returns true if and only if the type is a fixed-width, signed integer.
22172217 pub fn isSignedInt(ty: Type, mod: *const Module) bool {
22182218 return switch (ty.toIntern()) {
2219 .c_char_type, .isize_type, .c_short_type, .c_int_type, .c_long_type, .c_longlong_type => true,
2219 .c_char_type => mod.getTarget().charSignedness() == .signed,
2220 .isize_type, .c_short_type, .c_int_type, .c_long_type, .c_longlong_type => true,
22202221 else => switch (mod.intern_pool.indexToKey(ty.toIntern())) {
22212222 .int_type => |int_type| int_type.signedness == .signed,
22222223 else => false,
......@@ -2227,6 +2228,7 @@ pub const Type = struct {
22272228 /// Returns true if and only if the type is a fixed-width, unsigned integer.
22282229 pub fn isUnsignedInt(ty: Type, mod: *const Module) bool {
22292230 return switch (ty.toIntern()) {
2231 .c_char_type => mod.getTarget().charSignedness() == .unsigned,
22302232 .usize_type, .c_ushort_type, .c_uint_type, .c_ulong_type, .c_ulonglong_type => true,
22312233 else => switch (mod.intern_pool.indexToKey(ty.toIntern())) {
22322234 .int_type => |int_type| int_type.signedness == .unsigned,
......@@ -2257,7 +2259,7 @@ pub const Type = struct {
22572259 },
22582260 .usize_type => return .{ .signedness = .unsigned, .bits = target.ptrBitWidth() },
22592261 .isize_type => return .{ .signedness = .signed, .bits = target.ptrBitWidth() },
2260 .c_char_type => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.char) },
2262 .c_char_type => return .{ .signedness = mod.getTarget().charSignedness(), .bits = target.c_type_bit_size(.char) },
22612263 .c_short_type => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.short) },
22622264 .c_ushort_type => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.ushort) },
22632265 .c_int_type => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.int) },
test/behavior.zig+1
......@@ -145,6 +145,7 @@ test {
145145 _ = @import("behavior/bugs/15778.zig");
146146 _ = @import("behavior/byteswap.zig");
147147 _ = @import("behavior/byval_arg_var.zig");
148 _ = @import("behavior/c_char_signedness.zig");
148149 _ = @import("behavior/call.zig");
149150 _ = @import("behavior/cast.zig");
150151 _ = @import("behavior/cast_int.zig");
test/behavior/c_char_signedness.zig created+10
......@@ -0,0 +1,10 @@
1const std = @import("std");
2const expectEqual = std.testing.expectEqual;
3const c = @cImport({
4 @cInclude("limits.h");
5});
6
7test "c_char signedness" {
8 try expectEqual(@as(c_char, c.CHAR_MIN), std.math.minInt(c_char));
9 try expectEqual(@as(c_char, c.CHAR_MAX), std.math.maxInt(c_char));
10}