shithub: scc

Download patch

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;