~mcf/cproc

435454f6041216d2c38e507c860737c23e3e50fc — Michael Forney 2 years ago 3c039b1
Check for negative array lengths/indices
5 files changed, 10 insertions(+), 8 deletions(-)

M decl.c
M expr.c
M expr.h
M init.c
M stmt.c
M decl.c => decl.c +4 -4
@@ 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)

M expr.c => expr.c +3 -1
@@ 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;
}


M expr.h => expr.h +1 -1
@@ 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

M init.c => init.c +1 -1
@@ 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)

M stmt.c => stmt.c +1 -1
@@ 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);