scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit 618d3316287444bf57deb532c9d105f7049335cf
parent 99083f8dd0647e0f1a455918c7ccd0152f753895
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Mon,  7 Sep 2015 17:16:11 +0200

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.

Diffstat:
Mcc1/fold.c | 45++++++++++++++++++---------------------------
1 file changed, 18 insertions(+), 27 deletions(-)

diff --git a/cc1/fold.c b/cc1/fold.c @@ -197,7 +197,7 @@ foldint(int op, Symbol *res, TINT l, TINT r) } 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 @@ folduint(int op, Symbol *res, TINT l, TINT r) 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 @@ fold(int op, Type *tp, Node *lp, Node *rp) { Symbol *rs, *ls; Node *np; + Type *optype; int type; if ((op == ODIV || op == OMOD) && cmpnode(rp, 0)) { @@ -319,31 +319,22 @@ fold(int op, Type *tp, Node *lp, Node *rp) } 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); return np;