ref: b86fdca96b49c9000d32995a427f2ac8fad4ef6a
parent: 73e8f02ee56e42272698ef92ec8b593cec130843
parent: 75f20c4db1212d43aadc16c32fc9b507b47f9524
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Fri Jul 24 13:27:23 EDT 2015
Merge branch 'master' of ssh://suckless.org/gitrepos/scc Conflicts: cc1/cc1.h
--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -327,10 +327,13 @@
extern Node *sizeofnode(Type *tp);
extern void freetree(Node *np);
extern Node *simplify(unsigned char, Type *tp, Node *lp, Node *rp);
+extern Node *usimplify(unsigned char op, Type *tp, Node *np);
#define BTYPE(np) ((np)->type->op)
/* expr.c */
extern Node *expr(void), *negate(Node *np), *constexpr(void);
+extern Node *convert(Node *np, Type *tp1, char iscast);
+extern Node *iszero(Node *np), *eval(Node *np), *iconstexpr(void);
/* cpp.c */
extern void icpp(void);
--- a/cc1/code.c
+++ b/cc1/code.c
@@ -463,8 +463,6 @@
case OOR:
FOLDINT(sym, ls, rs, ||);
break;
- default:
- abort();
}
break;
case FLOAT:
@@ -480,4 +478,46 @@
no_simplify:
return node(op, tp, lp, rp);
+}
+
+#define UFOLDINT(sym, ls, op) (((sym)->type->sign) ? \
+ ((sym)->u.i = (op (ls)->u.i)) : \
+ ((sym)->u.u = (op (ls)->u.u)))
+
+Node *
+usimplify(unsigned char op, Type *tp, Node *np)
+{
+ Symbol *sym, *ns;
+
+ if (!np->constant)
+ goto no_simplify;
+ ns = np->sym;
+
+ switch (tp->op) {
+ case INT:
+ switch (op) {
+ case ONEG:
+ sym = newsym(NS_IDEN);
+ sym->type = tp;
+ UFOLDINT(sym, ns, -);
+ break;
+ case OCPL:
+ sym = newsym(NS_IDEN);
+ sym->type = tp;
+ UFOLDINT(sym, ns, ~);
+ break;
+ default:
+ goto no_simplify;
+ }
+ break;
+ case FLOAT:
+ /* TODO: implement floats */
+ default:
+ goto no_simplify;
+ }
+
+ return constnode(sym);
+
+no_simplify:
+ return node(op, tp, np, NULL);
}
--- 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
@@ -88,7 +88,7 @@
case FLOAT:
if (op == OADD)
return np;
- return node(op, np->type, np, NULL);
+ return usimplify(op, np->type, np);
default:
error("unary operator requires integer operand");
}
@@ -100,7 +100,7 @@
np = eval(np);
if (BTYPE(np) != INT)
error("unary operator requires integer operand");
- return node(op, np->type, np, NULL);
+ return usimplify(op, np->type, np);
}
static Node *
@@ -123,13 +123,18 @@
if (eqtype(np->type, tp))
return np;
switch (BTYPE(np)) {
- case ENUM: case INT: case FLOAT:
+ case ENUM:
+ case INT:
+ case FLOAT:
switch (tp->op) {
case PTR:
if (!iscast || BTYPE(np) == FLOAT)
return NULL;
/* PASSTHROUGH */
- case INT: case FLOAT: case ENUM: case VOID:
+ case INT:
+ case FLOAT:
+ case ENUM:
+ case VOID:
break;
default:
return NULL;
@@ -137,7 +142,9 @@
break;
case PTR:
switch (tp->op) {
- case ENUM: case INT: case VOID: /* TODO: allow p = 0 */
+ case ENUM: /* TODO: allow p = 0 */
+ case INT:
+ case VOID:
if (!iscast)
return NULL;;
break;
@@ -851,9 +858,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
@@ -9,8 +9,6 @@
Symbol *curfun;
-extern Node *convert(Node *np, Type *tp1, char iscast);
-extern Node *iszero(Node *np), *eval(Node *np);
static void stmt(Symbol *lbreak, Symbol *lcont, Caselist *lswitch);
static void
@@ -251,9 +249,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;