cproc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/cproc
Log | Files | Refs | Submodules | README | LICENSE

commit 1461f251570cb768122fc7ab2040b1d32366651e
parent 307293d3666c554b8eaff8736d0be001b85e867d
Author: Michael Forney <mforney@mforney.org>
Date:   Sun,  2 Jun 2019 18:18:06 -0700

decl: Disallow enumerator values that aren't representable as 'int'

Diffstat:
Mdecl.c | 19++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/decl.c b/decl.c @@ -150,7 +150,7 @@ static struct type * tagspec(struct scope *s) { struct type *t; - char *tag; + char *tag, *name; enum typekind kind; struct decl *d; struct expr *e; @@ -217,18 +217,27 @@ tagspec(struct scope *s) break; case TYPEENUM: for (i = 0; tok.kind == TIDENT; ++i) { - d = mkdecl(DECLCONST, &typeint, QUALNONE, LINKNONE); - scopeputdecl(s, tok.lit, d); + name = tok.lit; next(); if (consume(TASSIGN)) { e = constexpr(s); if (e->kind != EXPRCONST || !(e->type->prop & 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; + if (e->type->basic.issigned && i >= 1ull << 63) { + if (i < -1ull << 31) + goto invalid; + t->basic.issigned = true; + } else if (i >= 1ull << 31) { + goto invalid; + } + } else if (i == 1ull << 31) { + invalid: + error(&tok.loc, "enumerator '%s' value cannot be represented as 'int'", name); } + d = mkdecl(DECLCONST, &typeint, QUALNONE, LINKNONE); d->value = mkintconst(t->repr, i); + scopeputdecl(s, name, d); if (!consume(TCOMMA)) break; }