shithub: scc

Download patch

ref: 05cbd37b24f18d713c5632cb2639bc38eaab13ec
parent: 045728bdd4ff3888733cbf0ae65a93b15d39c2ec
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Tue Aug 9 10:22:25 EDT 2016

[cc1] Fix commit 60276b9

The commit 60276b9 was decaying everything when it was
calling postfix(), but this was not the correct behaviour. This
situation happend always that needed to call to primary(),
and there are some cases where we do not want to decay
(for example with the operator &).

--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -739,43 +739,6 @@
 	return node(OCALL, rettype, np, par);
 }
 
-static Node *
-postfix(Node *lp, int issizeof)
-{
-	Node *rp;
-
-	if (!lp)
-		lp = primary();
-	for (;;) {
-		if (!issizeof)
-			lp = decay(lp);
-		switch (yytoken) {
-		case '[':
-			next();
-			rp = expr();
-			lp = array(lp, rp);
-			expect(']');
-			break;
-		case DEC:
-		case INC:
-			lp = incdec(lp, (yytoken == INC) ? OINC : ODEC);
-			next();
-			break;
-		case INDIR:
-			lp = content(OPTR, lp);
-		case '.':
-			lp = field(lp);
-			break;
-		case '(':
-			lp = arguments(lp);
-			lp->flags |= NEFFECT;
-			break;
-		default:
-			return lp;
-		}
-	}
-}
-
 static Node *unary(int);
 
 static Type *
@@ -802,7 +765,7 @@
 		tp = typename();
 		break;
 	default:
-		tp = typeof(unary(1));
+		tp = typeof(unary(0));
 		break;
 	}
 	expect(')');
@@ -809,19 +772,68 @@
 	return tp;
 }
 
-static Node *cast(void);
+static Node *
+postfix(Node *lp)
+{
+	Node *rp;
 
+	for (;;) {
+		switch (yytoken) {
+		case '[':
+		case DEC:
+		case INC:
+		case INDIR:
+		case '.':
+		case '(':
+			lp = decay(lp);
+			switch (yytoken) {
+			case '[':
+				next();
+				rp = expr();
+				expect(']');
+				lp = array(lp, rp);
+				break;
+			case DEC:
+			case INC:
+				lp = incdec(lp, (yytoken == INC) ? OINC : ODEC);
+				next();
+				break;
+			case INDIR:
+				lp = content(OPTR, lp);
+			case '.':
+				lp = field(lp);
+				break;
+			case '(':
+				lp = arguments(lp);
+				lp->flags |= NEFFECT;
+				break;
+			}
+			break;
+		default:
+			return lp;
+		}
+	}
+}
+
+static Node *cast(int);
+
 static Node *
-unary(int issizeof)
+unary(int needdecay)
 {
-	Node *(*fun)(char, Node *);
+	Node *(*fun)(char, Node *), *np;
 	char op;
 	Type *tp;
 
 	switch (yytoken) {
+	case '!': op = 0;     fun = negation;     break;
+	case '+': op = OADD;  fun = numericaluop; break;
+	case '-': op = ONEG;  fun = numericaluop; break;
+	case '~': op = OCPL;  fun = integeruop;   break;
+	case '&': op = OADDR; fun = address;      break;
+	case '*': op = OPTR;  fun = content;      break;
 	case SIZEOF:
 		next();
-		tp = (yytoken == '(') ? sizeexp() : typeof(unary(1));
+		tp = (yytoken == '(') ? sizeexp() : typeof(unary(0));
 		if (!(tp->prop & TDEFINED))
 			errorp("sizeof applied to an incomplete type");
 		return sizeofnode(tp);
@@ -829,22 +841,24 @@
 	case DEC:
 		op = (yytoken == INC) ? OA_ADD : OA_SUB;
 		next();
-		return incdec(unary(issizeof), op);
-	case '!': op = 0;     fun = negation;     break;
-	case '+': op = OADD;  fun = numericaluop; break;
-	case '-': op = ONEG;  fun = numericaluop; break;
-	case '~': op = OCPL;  fun = integeruop;   break;
-	case '&': op = OADDR; fun = address;      break;
-	case '*': op = OPTR;  fun = content;      break;
-	default:  return postfix(NULL, issizeof);
+		np = incdec(unary(1), op);
+		goto chk_decay;
+	default:
+		np = postfix(primary());
+		goto chk_decay;
 	}
 
 	next();
-	return (*fun)(op, cast());
+	np = (*fun)(op, cast(op != OADDR));
+
+chk_decay:
+	if (needdecay)
+		np = decay(np);
+	return np;
 }
 
 static Node *
-cast(void)
+cast(int needdecay)
 {
 	Node *lp, *rp;
 	Type *tp;
@@ -851,7 +865,7 @@
 	static int nested;
 
 	if (!accept('('))
-		return unary(0);
+		return unary(needdecay);
 
 	switch (yytoken) {
 	case TQUALIFIER:
@@ -866,7 +880,7 @@
 		case ARY:
 			error("cast specifies an array type");
 		default:
-			lp = cast();
+			lp = cast(needdecay);
 			if ((rp = convert(lp,  tp, 1)) == NULL)
 				error("bad type conversion requested");
 			rp->flags &= ~NLVAL;
@@ -880,7 +894,7 @@
 		rp = expr();
 		--nested;
 		expect(')');
-		rp = postfix(rp, 0);
+		rp = postfix(rp);
 		break;
 	}
 
@@ -893,7 +907,7 @@
 	Node *np, *(*fun)(char, Node *, Node *);
 	char op;
 
-	np = cast();
+	np = cast(1);
 	for (;;) {
 		switch (yytoken) {
 		case '*': op = OMUL; fun = arithmetic; break;
@@ -902,7 +916,7 @@
 		default: return np;
 		}
 		next();
-		np = (*fun)(op, np, cast());
+		np = (*fun)(op, np, cast(1));
 	}
 }