shithub: scc

Download patch

ref: 618d3316287444bf57deb532c9d105f7049335cf
parent: 99083f8dd0647e0f1a455918c7ccd0152f753895
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Mon Sep 7 13:16:11 EDT 2015

Fix constant folding type

The code was confusing the type of the expression and the type of
the operands. We have 3 functions, foldint, folduint and foldfloat,
which only depend of the type of the operands, not of the type
of the generated node.

--- a/cc1/fold.c
+++ b/cc1/fold.c
@@ -197,7 +197,7 @@
 }
 
 static bool
-folduint(int op, Symbol *res, TINT l, TINT r)
+folduint(int op, Symbol *res, TUINT l, TUINT r)
 {
 	TINT i;
 	TUINT u;
@@ -215,22 +215,21 @@
 	case OBOR:  u = l | r;  break;
 	case ONEG:  u = -l;     break;
 	case OCPL:  u = ~l;     break;
-	case OAND:  i = l && r; goto unsign;
-	case OOR:   i = l || r; goto unsign;
-	case OLT:   i = l < r;  goto unsign;
-	case OGT:   i = l > r;  goto unsign;
-	case OGE:   i = l >= r; goto unsign;
-	case OLE:   i = l <= r; goto unsign;
-	case OEQ:   i = l == r; goto unsign;
-	case ONE:   i = l != r; goto unsign;
+	case OAND:  i = l && r; goto sign;
+	case OOR:   i = l || r; goto sign;
+	case OLT:   i = l < r;  goto sign;
+	case OGT:   i = l > r;  goto sign;
+	case OGE:   i = l >= r; goto sign;
+	case OLE:   i = l <= r; goto sign;
+	case OEQ:   i = l == r; goto sign;
+	case ONE:   i = l != r; goto sign;
 	default:    return 0;
 	}
 
-sign:
 	res->u.u = u;
 	return 1;
 
-unsign:
+sign:
 	res->u.i = i;
 	return 1;
 }
@@ -311,6 +310,7 @@
 {
 	Symbol *rs, *ls;
 	Node *np;
+	Type *optype;
 	int type;
 
 	if ((op == ODIV || op == OMOD) && cmpnode(rp, 0)) {
@@ -319,30 +319,21 @@
 	}
 	if (!lp->constant || rp && !rp->constant)
 		return NULL;
-
+	optype = lp->type;
 	ls = lp->sym;
 	rs = (rp) ? rp->sym : NULL;
 
-	/*
-	 * Comparision nodes have integer type
-	 * but the operands can have different
-	 * type.
-	 */
-	type = (isnodecmp(op)) ? BTYPE(lp) : tp->op;
-	switch (type) {
-	case PTR:
+	switch (type = optype->op) {
 	case INT:
-		type = (tp->sign) ? INT : UNSIGNED;
-		break;
+		if (!optype->sign)
+			type = UNSIGNED;
+	case PTR:
 	case FLOAT:
-		type = FLOAT;
-		break;
+		if ((np = foldconst(type, op, tp, ls, rs)) != NULL)
+			break;
 	default:
 		return NULL;
 	}
-
-	if ((np = foldconst(type, op, tp, ls, rs)) == NULL)
-		return NULL;
 
 	freetree(lp);
 	freetree(rp);