From 333089c44a1c6c853448365a2f043bf5ec3f29e6 Mon Sep 17 00:00:00 2001 From: Evan Haas Date: Thu, 2 May 2024 21:49:58 -0700 Subject: [PATCH] Parser: avoid overflow when enum backed by large _BitInt --- src/aro/Parser.zig | 4 ++-- test/cases/_BitInt.c | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/aro/Parser.zig b/src/aro/Parser.zig index 0b200a34..31fa9c17 100644 --- a/src/aro/Parser.zig +++ b/src/aro/Parser.zig @@ -2701,8 +2701,6 @@ const Enumerator = struct { return; } if (try e.res.val.add(e.res.val, Value.one, e.res.ty, p.comp)) { - const byte_size = e.res.ty.sizeof(p.comp).?; - const bit_size: u8 = @intCast(if (e.res.ty.isUnsignedInt(p.comp)) byte_size * 8 else byte_size * 8 - 1); if (e.fixed) { try p.errStr(.enum_not_representable_fixed, tok, try p.typeStr(e.res.ty)); return; @@ -2711,6 +2709,8 @@ const Enumerator = struct { try p.errTok(.enumerator_overflow, tok); break :blk larger; } else blk: { + const signed = !e.res.ty.isUnsignedInt(p.comp); + const bit_size: u8 = @intCast(e.res.ty.bitSizeof(p.comp).? - @intFromBool(signed)); try p.errExtra(.enum_not_representable, tok, .{ .pow_2_as_string = bit_size }); break :blk Type{ .specifier = .ulong_long }; }; diff --git a/test/cases/_BitInt.c b/test/cases/_BitInt.c index 5ad4cced..4f1e83d2 100644 --- a/test/cases/_BitInt.c +++ b/test/cases/_BitInt.c @@ -22,6 +22,11 @@ int z = 0uwb; int x = 1'2; _Static_assert(((int)-18446744073709551616WB) == 0); +enum E: _BitInt(512) { + A=6703903964971298549787012499102923063739682910296196688861780721860882015036773488400937149083451713845015929093243025426876941405973284973216824503042047WB, + B, +}; + #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:14:8: error: signed _BitInt must have a bit size of at least 2" \ @@ -30,3 +35,5 @@ _Static_assert(((int)-18446744073709551616WB) == 0); "_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'" \ +