ref: a564bb5b0d450239b5e5f7379a631dee4593ca28
parent: 18071c940a707f9de54540e4ddbb405bbf8cba19
author: Roberto E. Vargas Caballero <[email protected]>
date: Thu Jul 23 14:30:53 EDT 2015
Force expressions in case and array sizes to be int constants C89/C90 needs integer constant in array sizes (C99 admits VLA, but this is something we will see later), so the size must be known at compile time. In the same way, case labels must be a constant integer expression.
--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -330,7 +330,8 @@
extern Node *usimplify(unsigned char op, Type *tp, Node *np);
/* expr.c */
-extern Node *expr(void), *negate(Node *np), *constexpr(void);
+extern Node *expr(void), *negate(Node *np), *constexpr(void),
+ *iconstexpr(void);
/* cpp.c */
extern void icpp(void);
--- a/cc1/decl.c
+++ b/cc1/decl.c
@@ -39,17 +39,16 @@
static struct dcldata *
arydcl(struct dcldata *dp)
{
- Node *np;
+ Node *np = NULL;
TINT n;
expect('[');
- np = (yytoken != ']') ? constexpr() : NULL;
+ if (yytoken != ']') {
+ if ((np = iconstexpr()) == NULL)
+ error("invalid storage size");
+ }
expect(']');
- /*
- * TODO: check that the type of the constant expression
- * is the correct, that in this case should be int
- */
n = (np == NULL) ? 0 : np->sym->u.i;
freetree(np);
--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -853,9 +853,27 @@
Node *np;
np = ternary();
- if (!np->constant)
- error("constant expression required");
+ if (!np->constant) {
+ freetree(np);
+ return NULL;
+ }
return np;
+}
+
+Node *
+iconstexpr(void)
+{
+ Node *np;
+
+ if ((np = constexpr()) == NULL)
+ return NULL;
+
+ if (np->type->op != INT) {
+ freetree(np);
+ return NULL;
+ }
+
+ return convert(np, inttype, 0);
}
Node *
--- a/cc1/stmt.c
+++ b/cc1/stmt.c
@@ -250,9 +250,8 @@
expect(CASE);
if (!lswitch)
error("case label not within a switch statement");
- np = expr();
- if ((np = convert(np, inttype, 0)) == NULL)
- error("incorrect type in case statement");
+ if ((np = iconstexpr()) == NULL)
+ error("case label does not reduce to an integer constant");
expect(':');
pcase = xmalloc(sizeof(*pcase));
pcase->expr = np;