shithub: scc

Download patch

ref: ec361b9959f7434a634a1c7e6dc1315b890a9c63
parent: 0490f2f14e257b73206da53fd88329223702cf2f
author: Roberto E. Vargas Caballero <[email protected]>
date: Tue Sep 27 06:26:04 EDT 2016

[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.

--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -321,7 +321,7 @@
 	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 @@
 
 	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 @@
 		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;
--- a/cc1/tests/test036.c
+++ b/cc1/tests/test036.c
@@ -19,28 +19,28 @@
 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
--- 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: