aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Forney <mforney@mforney.org>2019-04-14 00:19:03 -0700
committerMichael Forney <mforney@mforney.org>2019-04-14 00:19:57 -0700
commit44c0cbd2080fce59bffe8b91f4ec44512710f2c5 (patch)
tree9fa10d03f004acd5722eeccaf37fbacf5b971e28
parenta0c8910f8f834b833ce2b8a38915b7857875c942 (diff)
decl: Make signedness of enum types match gcc
-rw-r--r--decl.c13
-rw-r--r--tests/compatible-enum-types.c7
-rw-r--r--tests/compatible-enum-types.qbe1
3 files changed, 15 insertions, 6 deletions
diff --git a/decl.c b/decl.c
index d56b2cb..1dc1310 100644
--- a/decl.c
+++ b/decl.c
@@ -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 }