scc

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

commit 56b94fe84a71df35ca1cbdd299985b2fe480c3ba
parent a237a1813e294b9c3a41d4e06c2f5d678b194a28
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue, 27 Sep 2016 10:26:04 +0200

[cc1] Fix pre increment/decrement for pointers

Pre increment/decrement for pointers was broken, mainly
because pointers are not arithmetic types, and the size
of the pointers were calculated in two different places.
Another problem was related to the fact that post inc/dec
generates an op but pre inc/dec generates another one,
and the tests were checking only against the values
generated for post operators.

Diffstat:
Mcc1/expr.c | 26+++++++++++++++-----------
Mcc1/tests/test036.c | 16++++++++--------
Mcc1/tests/test065.c | 2+-
3 files changed, 24 insertions(+), 20 deletions(-)

diff --git a/cc1/expr.c b/cc1/expr.c @@ -321,7 +321,7 @@ parithmetic(char op, Node *lp, Node *rp) rp = simplify(OMUL, sizettype, rp, size); rp = convert(rp, tp, 1); - return simplify(OADD, tp, lp, rp); + return simplify(op, tp, lp, rp); incomplete: errorp("invalid use of undefined type"); @@ -339,13 +339,19 @@ arithmetic(char op, Node *lp, Node *rp) if ((ltp->prop & TARITH) && (rtp->prop & TARITH)) { arithconv(&lp, &rp); - } else if ((ltp->op == PTR || rtp->op == PTR) && - (op == OADD || op == OSUB)) { - return parithmetic(op, rp, lp); - } else if (op != OINC && op != ODEC) { - errorp("incorrect arithmetic operands"); + return simplify(op, lp->type, lp, rp); + } else if ((ltp->op == PTR || rtp->op == PTR)) { + switch (op) { + case OADD: + case OSUB: + case OA_ADD: + case OA_SUB: + case OINC: + case ODEC: + return parithmetic(op, rp, lp); + } } - return simplify(op, lp->type, lp, rp); + errorp("incorrect arithmetic operands"); } static Node * @@ -563,12 +569,10 @@ incdec(Node *np, char op) return np; } else if (tp->op == PTR && !(tp->type->prop & TDEFINED)) { errorp("%s of pointer to an incomplete type", - (op == OINC) ? "increment" : "decrement"); + (op == OINC || op == OA_ADD) ? "increment" : "decrement"); return np; - } else if (tp->prop & TARITH) { + } else if (tp->op == PTR || (tp->prop & TARITH)) { inc = constnode(one); - } else if (tp->op == PTR) { - inc = sizeofnode(tp->type); } else { errorp("wrong type argument to increment or decrement"); return np; diff --git a/cc1/tests/test036.c b/cc1/tests/test036.c @@ -19,28 +19,28 @@ R7 I "n L9 e L10 - R1 @I R2 #N2 :iP @I :I + R1 @I R2 #P2 :iP @I :I v L12 #I7 L12 - R1 @I R2 #N2 :iP @I :I + R1 @I R2 #P2 :iP @I :I v L13 #I6 L13 - R1 @I R2 #N2 :iP @I :I + R1 @I R2 #P2 :iP @I :I v L14 #I5 L14 - R1 @I R2 #N2 :iP @I :I + R1 @I R2 #P2 :iP @I :I v L15 #I4 L15 - R1 @I R2 #N2 :iP @I :I + R1 @I R2 #P2 :iP @I :I v L16 #I3 L16 - R1 @I R2 #N2 :iP @I :I + R1 @I R2 #P2 :iP @I :I v L17 #I2 L17 - R1 @I R2 #N2 :iP @I :I + R1 @I R2 #P2 :iP @I :I v L18 #I1 L18 - R1 @I R2 #N2 :iP @I :I + R1 @I R2 #P2 :iP @I :I y L10 R7 #I1 :-I #I0 >I b L11 diff --git a/cc1/tests/test065.c b/cc1/tests/test065.c @@ -4,7 +4,7 @@ name: TEST065 description: Test decay mixed with * operators error: -test065.c:65: error: decrement of pointer to an incomplete type +test065.c:65: error: increment of pointer to an incomplete type test065.c:65: error: invalid use of undefined type test065.c:66: warning: 'argv' defined but not used output: