diff options
author | Michael Forney <mforney@mforney.org> | 2019-04-14 00:19:03 -0700 |
---|---|---|
committer | Michael Forney <mforney@mforney.org> | 2019-04-14 00:19:57 -0700 |
commit | 44c0cbd2080fce59bffe8b91f4ec44512710f2c5 (patch) | |
tree | 9fa10d03f004acd5722eeccaf37fbacf5b971e28 | |
parent | a0c8910f8f834b833ce2b8a38915b7857875c942 (diff) |
decl: Make signedness of enum types match gcc
-rw-r--r-- | decl.c | 13 | ||||
-rw-r--r-- | tests/compatible-enum-types.c | 7 | ||||
-rw-r--r-- | tests/compatible-enum-types.qbe | 1 |
3 files changed, 15 insertions, 6 deletions
@@ -154,6 +154,7 @@ tagspec(struct scope *s) char *tag; enum typekind kind; struct decl *d; + struct expr *e; struct structbuilder b; uint64_t i; @@ -182,7 +183,7 @@ tagspec(struct scope *s) } else { t = mktype(kind); if (kind == TYPEBASIC) { - *t = typeint; + *t = typeuint; t->basic.kind = BASICENUM; } else { t->repr = &i64; // XXX @@ -217,8 +218,14 @@ tagspec(struct scope *s) d = mkdecl(DECLCONST, &typeint, QUALNONE, LINKNONE); scopeputdecl(s, tok.lit, d); next(); - if (consume(TASSIGN)) - i = intconstexpr(s, true); + if (consume(TASSIGN)) { + e = constexpr(s); + if (e->kind != EXPRCONST || !(typeprop(e->type) & PROPINT)) + error(&tok.loc, "expected integer constant expression"); + if (e->type->basic.issigned && e->constant.i >= 1ull << 63) + t->basic.issigned = true; + i = e->constant.i; + } d->value = mkintconst(t->repr, i); if (!consume(TCOMMA)) break; diff --git a/tests/compatible-enum-types.c b/tests/compatible-enum-types.c index e320966..c605e90 100644 --- a/tests/compatible-enum-types.c +++ b/tests/compatible-enum-types.c @@ -1,3 +1,4 @@ -enum E {A = -1, B}; -enum E x; -int x; +enum {A = 1} x; +unsigned x; +enum {B = -1} y; +int y; diff --git a/tests/compatible-enum-types.qbe b/tests/compatible-enum-types.qbe index 7cf0e40..a9a9224 100644 --- a/tests/compatible-enum-types.qbe +++ b/tests/compatible-enum-types.qbe @@ -1 +1,2 @@ export data $x = align 4 { z 4 } +export data $y = align 4 { z 4 } |