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 435454f6041216d2c38e507c860737c23e3e50fc
parent 3c039b17296283392f821cd26c0ef584f0d8fa86
Author: Michael Forney <mforney@mforney.org>
Date:   Sun, 24 Feb 2019 16:11:16 -0800

Check for negative array lengths/indices

Diffstat:
Mdecl.c | 8++++----
Mexpr.c | 4+++-
Mexpr.h | 2+-
Minit.c | 2+-
Mstmt.c | 2+-
5 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/decl.c b/decl.c @@ -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) diff --git a/expr.c b/expr.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; } diff --git a/expr.h b/expr.h @@ -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 diff --git a/init.c b/init.c @@ -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) diff --git a/stmt.c b/stmt.c @@ -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);