Skip to content

Commit

Permalink
Type: print _BitInt size in diagnostics
Browse files Browse the repository at this point in the history
  • Loading branch information
wrongnull authored Jul 14, 2024
1 parent 7c7d5e1 commit 6c33c4c
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 35 deletions.
13 changes: 9 additions & 4 deletions src/aro/Diagnostics/messages.def
Original file line number Diff line number Diff line change
Expand Up @@ -2058,17 +2058,22 @@ bit_int
.suppress_version = .c23

unsigned_bit_int_too_small
.msg = "{s} must have a bit size of at least 1"
.msg = "{s}unsigned _BitInt must have a bit size of at least 1"
.extra = .str
.kind = .@"error"

signed_bit_int_too_small
.msg = "{s} must have a bit size of at least 2"
.msg = "{s}signed _BitInt must have a bit size of at least 2"
.extra = .str
.kind = .@"error"

bit_int_too_big
.msg = "{s} of bit sizes greater than " ++ std.fmt.comptimePrint("{d}", .{Properties.max_bits}) ++ " not supported"
unsigned_bit_int_too_big
.msg = "{s}unsigned _BitInt of bit sizes greater than " ++ std.fmt.comptimePrint("{d}", .{Properties.max_bits}) ++ " not supported"
.extra = .str
.kind = .@"error"

signed_bit_int_too_big
.msg = "{s}signed _BitInt of bit sizes greater than " ++ std.fmt.comptimePrint("{d}", .{Properties.max_bits}) ++ " not supported"
.extra = .str
.kind = .@"error"

Expand Down
11 changes: 0 additions & 11 deletions src/aro/Parser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8505,17 +8505,6 @@ fn bitInt(p: *Parser, base: u8, buf: []const u8, suffix: NumberSuffix, tok_i: To
// value of the constant is positive or was specified in hexadecimal or octal notation.
const sign_bits = @intFromBool(suffix.isSignedInteger());
const bits_needed = count + sign_bits;
if (bits_needed > Compilation.bit_int_max_bits) {
const specifier: Type.Builder.Specifier = switch (suffix) {
.WB => .{ .bit_int = 0 },
.UWB => .{ .ubit_int = 0 },
.IWB => .{ .complex_bit_int = 0 },
.IUWB => .{ .complex_ubit_int = 0 },
else => unreachable,
};
try p.errStr(.bit_int_too_big, tok_i, specifier.str(p.comp.langopts).?);
return error.ParsingFailed;
}
break :blk @intCast(bits_needed);
};

Expand Down
24 changes: 9 additions & 15 deletions src/aro/Type.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1616,9 +1616,6 @@ pub const Builder = struct {
.int128 => "__int128",
.sint128 => "signed __int128",
.uint128 => "unsigned __int128",
.bit_int => "_BitInt",
.sbit_int => "signed _BitInt",
.ubit_int => "unsigned _BitInt",
.complex_char => "_Complex char",
.complex_schar => "_Complex signed char",
.complex_uchar => "_Complex unsigned char",
Expand Down Expand Up @@ -1648,9 +1645,6 @@ pub const Builder = struct {
.complex_int128 => "_Complex __int128",
.complex_sint128 => "_Complex signed __int128",
.complex_uint128 => "_Complex unsigned __int128",
.complex_bit_int => "_Complex _BitInt",
.complex_sbit_int => "_Complex signed _BitInt",
.complex_ubit_int => "_Complex unsigned _BitInt",

.fp16 => "__fp16",
.float16 => "_Float16",
Expand Down Expand Up @@ -1759,19 +1753,20 @@ pub const Builder = struct {
.complex_uint128 => ty.specifier = .complex_uint128,
.bit_int, .sbit_int, .ubit_int, .complex_bit_int, .complex_ubit_int, .complex_sbit_int => |bits| {
const unsigned = b.specifier == .ubit_int or b.specifier == .complex_ubit_int;
const complex_str = if (b.complex_tok != null) "_Complex " else "";
if (unsigned) {
if (bits < 1) {
try p.errStr(.unsigned_bit_int_too_small, b.bit_int_tok.?, b.specifier.str(p.comp.langopts).?);
try p.errStr(.unsigned_bit_int_too_small, b.bit_int_tok.?, complex_str);
return Type.invalid;
}
} else {
if (bits < 2) {
try p.errStr(.signed_bit_int_too_small, b.bit_int_tok.?, b.specifier.str(p.comp.langopts).?);
try p.errStr(.signed_bit_int_too_small, b.bit_int_tok.?, complex_str);
return Type.invalid;
}
}
if (bits > Compilation.bit_int_max_bits) {
try p.errStr(.bit_int_too_big, b.bit_int_tok.?, b.specifier.str(p.comp.langopts).?);
try p.errStr(if (unsigned) .unsigned_bit_int_too_big else .signed_bit_int_too_big, b.bit_int_tok.?, complex_str);
return Type.invalid;
}
ty.specifier = if (b.complex_tok != null) .complex_bit_int else .bit_int;
Expand Down Expand Up @@ -2485,6 +2480,8 @@ fn printPrologue(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts
_ = try elem_ty.printPrologue(mapper, langopts, w);
try w.writeAll("' values)");
},
.bit_int => try w.print("{s} _BitInt({d})", .{ @tagName(ty.data.int.signedness), ty.data.int.bits }),
.complex_bit_int => try w.print("_Complex {s} _BitInt({d})", .{ @tagName(ty.data.int.signedness), ty.data.int.bits }),
else => try w.writeAll(Builder.fromType(ty).str(langopts).?),
}
return true;
Expand Down Expand Up @@ -2643,12 +2640,9 @@ pub fn dump(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w:
try ty.data.attributed.base.dump(mapper, langopts, w);
try w.writeAll(")");
},
else => {
try w.writeAll(Builder.fromType(ty).str(langopts).?);
if (ty.specifier == .bit_int or ty.specifier == .complex_bit_int) {
try w.print("({d})", .{ty.data.int.bits});
}
},
.bit_int => try w.print("{s} _BitInt({d})", .{ @tagName(ty.data.int.signedness), ty.data.int.bits }),
.complex_bit_int => try w.print("_Complex {s} _BitInt({d})", .{ @tagName(ty.data.int.signedness), ty.data.int.bits }),
else => try w.writeAll(Builder.fromType(ty).str(langopts).?),
}
}

Expand Down
5 changes: 5 additions & 0 deletions test/cases/_BitInt change size.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
_BitInt(10) x = 1.2;
_Complex unsigned _BitInt(10) y = 1.2;

#define EXPECTED_ERRORS "_BitInt change size.c:1:17: warning: implicit conversion from 'double' to 'signed _BitInt(10)' changes value from 1.2 to 1 [-Wfloat-conversion]"\
"_BitInt change size.c:2:35: warning: implicit conversion from 'double' to '_Complex unsigned _BitInt(10)' changes value from 1.2 to 1 [-Wfloat-conversion]"
4 changes: 2 additions & 2 deletions test/cases/_BitInt.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ enum E: _BitInt(512) {
_Static_assert(sizeof(_BitInt(65535)) == 8192, "");

#define EXPECTED_ERRORS "_BitInt.c:3:1: warning: '_BitInt' in C17 and earlier is a Clang extension' [-Wbit-int-extension]" \
"_BitInt.c:13:1: error: _BitInt of bit sizes greater than 65535 not supported" \
"_BitInt.c:13:1: error: signed _BitInt of bit sizes greater than 65535 not supported" \
"_BitInt.c:14:8: error: signed _BitInt must have a bit size of at least 2" \
"_BitInt.c:15:10: error: unsigned _BitInt must have a bit size of at least 1" \
"_BitInt.c:17:16: warning: '_BitInt' suffix for literals is a C23 extension [-Wc23-extensions]" \
"_BitInt.c:18:25: warning: '_BitInt' suffix for literals is a C23 extension [-Wc23-extensions]" \
"_BitInt.c:18:25: warning: '_BitInt' suffix for literals is a C23 extension [-Wc23-extensions]" \
"_BitInt.c:22:10: error: expected ';', found 'a character literal'" \
"_BitInt.c:27:5: error: enumerator value is not representable in the underlying type '_BitInt'" \
"_BitInt.c:27:5: error: enumerator value is not representable in the underlying type 'signed _BitInt(512)'" \

4 changes: 2 additions & 2 deletions test/cases/array of invalid.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
_BitInt(0) a[];
_BitInt(0) b[10];

#define EXPECTED_ERRORS "array of invalid.c:1:1: error: _BitInt must have a bit size of at least 2" \
"array of invalid.c:2:1: error: _BitInt must have a bit size of at least 2" \
#define EXPECTED_ERRORS "array of invalid.c:1:1: error: signed _BitInt must have a bit size of at least 2" \
"array of invalid.c:2:1: error: signed _BitInt must have a bit size of at least 2" \

2 changes: 1 addition & 1 deletion test/cases/constexpr.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ static_assert(!const_bool_false);
#define EXPECTED_ERRORS "constexpr.c:5:14: error: cannot combine with previous 'thread_local' specifier" \
"constexpr.c:7:19: error: invalid storage class on function parameter" \
"constexpr.c:7:1: error: illegal storage class on function" \
"constexpr.c:13:28: warning: implicit conversion from 'int' to '_BitInt' changes non-zero value from 4 to 0 [-Wconstant-conversion]" \
"constexpr.c:13:28: warning: implicit conversion from 'int' to 'signed _BitInt(2)' changes non-zero value from 4 to 0 [-Wconstant-conversion]" \

0 comments on commit 6c33c4c

Please sign in to comment.