From 9aeacf0551016870b466569cd0f11d73e157cb1b Mon Sep 17 00:00:00 2001 From: Evan Haas Date: Mon, 15 Apr 2024 21:36:17 -0700 Subject: [PATCH] Type: fix integer rank comparison for incomplete enums Fixes #681 --- src/aro/Type.zig | 5 +++++ test/cases/enum fixed.c | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/aro/Type.zig b/src/aro/Type.zig index cc660c3b..2364adcb 100644 --- a/src/aro/Type.zig +++ b/src/aro/Type.zig @@ -1318,6 +1318,10 @@ pub fn integerRank(ty: Type, comp: *const Compilation) usize { .typeof_expr => ty.data.expr.ty.integerRank(comp), .attributed => ty.data.attributed.base.integerRank(comp), + .@"enum" => { + std.debug.assert(real.data.@"enum".fixed); + return real.data.@"enum".tag_ty.integerRank(comp); + }, else => unreachable, }); } @@ -1325,6 +1329,7 @@ pub fn integerRank(ty: Type, comp: *const Compilation) usize { /// Returns true if `a` and `b` are integer types that differ only in sign pub fn sameRankDifferentSign(a: Type, b: Type, comp: *const Compilation) bool { if (!a.isInt() or !b.isInt()) return false; + if (a.hasIncompleteSize() or b.hasIncompleteSize()) return false; if (a.integerRank(comp) != b.integerRank(comp)) return false; return a.isUnsignedInt(comp) != b.isUnsignedInt(comp); } diff --git a/test/cases/enum fixed.c b/test/cases/enum fixed.c index 3bccbd6e..5c9dd94e 100644 --- a/test/cases/enum fixed.c +++ b/test/cases/enum fixed.c @@ -58,6 +58,19 @@ _Static_assert(__builtin_types_compatible_p(enum Unsigned, unsigned), ""); _Static_assert(!__builtin_types_compatible_p(enum Signed, enum Plain), ""); _Static_assert(!__builtin_types_compatible_p(enum Unsigned, enum Plain), ""); +void pointers(void) { + int x; + unsigned y; + + enum Signed *e1 = &x; + enum Signed *e2 = &y; + enum Unsigned *e3 = &x; + enum Unsigned *e4 = &y; + + enum Incomplete *i1 = &x; + enum Incomplete *i2 = &y; +} + #define EXPECTED_ERRORS "enum fixed.c:2:7: warning: enumeration types with a fixed underlying type are a Clang extension [-Wfixed-enum-extension]" \ "enum fixed.c:4:6: error: enumeration previously declared with fixed underlying type" \ "enum fixed.c:2:6: note: previous definition is here" \ @@ -67,3 +80,8 @@ _Static_assert(!__builtin_types_compatible_p(enum Unsigned, enum Plain), ""); "enum fixed.c:9:6: note: previous definition is here" \ "enum fixed.c:14:5: error: enumerator value is not representable in the underlying type 'unsigned char'" \ "enum fixed.c:18:5: error: enumerator value is not representable in the underlying type 'char'" \ + "enum fixed.c:66:23: warning: incompatible pointer types initializing 'enum Signed: int *' from incompatible type 'unsigned int *' converts between pointers to integer types with different sign [-Wpointer-sign]" \ + "enum fixed.c:67:25: warning: incompatible pointer types initializing 'enum Unsigned: unsigned int *' from incompatible type 'int *' [-Wincompatible-pointer-types]" \ + "enum fixed.c:70:27: warning: incompatible pointer types initializing 'enum Incomplete *' from incompatible type 'int *' [-Wincompatible-pointer-types]" \ + "enum fixed.c:71:27: warning: incompatible pointer types initializing 'enum Incomplete *' from incompatible type 'unsigned int *' [-Wincompatible-pointer-types]" \ +