diff options
-rw-r--r-- | decl.c | 8 | ||||
-rw-r--r-- | expr.c | 4 | ||||
-rw-r--r-- | expr.h | 2 | ||||
-rw-r--r-- | init.c | 2 | ||||
-rw-r--r-- | stmt.c | 2 |
5 files changed, 10 insertions, 8 deletions
@@ -212,7 +212,7 @@ tagspec(struct scope *s) scopeputdecl(s, tok.lit, d); next(); if (consume(TASSIGN)) - i = intconstexpr(s); + i = intconstexpr(s, true); d->value = mkintconst(t->repr, i); if (!consume(TCOMMA)) break; @@ -336,7 +336,7 @@ declspecs(struct scope *s, enum storageclass *sc, enum funcspecifier *fs, int *a if (t) { *align = t->align; } else { - i = intconstexpr(s); + i = intconstexpr(s, false); if (!i || i & (i - 1) || i > 16) error(&tok.loc, "invalid alignment: %d", i); *align = (int)i; @@ -511,7 +511,7 @@ declaratortypes(struct scope *s, struct list *result, char **name, bool allowabs i = 0; next(); } else { - i = intconstexpr(s); + i = intconstexpr(s, false); expect(TRBRACK, "after array length"); } if (tq) { @@ -712,7 +712,7 @@ decl(struct scope *s, struct function *f) if (consume(T_STATIC_ASSERT)) { expect(TLPAREN, "after _Static_assert"); - c = intconstexpr(s); + c = intconstexpr(s, true); expect(TCOMMA, "after static assertion expression"); expect(TSTRINGLIT, "after static assertion expression"); if (!c) @@ -847,13 +847,15 @@ condexpr(struct scope *s) } uint64_t -intconstexpr(struct scope *s) +intconstexpr(struct scope *s, bool allowneg) { struct expression *e; e = eval(condexpr(s)); if (e->kind != EXPRCONST || !(typeprop(e->type) & PROPINT)) error(&tok.loc, "not an integer constant expression"); + if (!allowneg && e->type->basic.issigned && e->constant.i > INT64_MAX) + error(&tok.loc, "integer constant expression cannot be negative"); return e->constant.i; } @@ -88,7 +88,7 @@ struct scope; struct expression *expr(struct scope *); struct expression *assignexpr(struct scope *); -uint64_t intconstexpr(struct scope *); +uint64_t intconstexpr(struct scope *, _Bool); void delexpr(struct expression *); void exprpromote(struct expression **); // XXX: move to type @@ -129,7 +129,7 @@ designator(struct scope *s, struct initparser *p) if (t->kind != TYPEARRAY) error(&tok.loc, "index designator is only valid for array types"); next(); - p->sub->idx = intconstexpr(s); + p->sub->idx = intconstexpr(s, false); if (t->incomplete) updatearray(t, p->sub->idx); else if (p->sub->idx >= t->array.length) @@ -52,7 +52,7 @@ stmt(struct function *f, struct scope *s) error(&tok.loc, "'case' label must be in switch"); label[0] = mkblock("switch_case"); funclabel(f, label[0]); - i = intconstexpr(s); + i = intconstexpr(s, true); switchcase(s->switchcases, i, label[0]); expect(TCOLON, "after case expression"); stmt(f, s); |