shithub: scc

Download patch

ref: 878d46d965b83832a939cc46707aa6f3b7e5d30e
parent: 912280612a54370fb154224164cccf24b95d1129
parent: 6e9d1522e50e81ab34916a0cf02fd838db7771c8
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Wed Jun 22 14:32:58 EDT 2022

Merge remote-tracking branch 'origin/master'

--- a/src/cmd/cc/cc1/cc1.h
+++ b/src/cmd/cc/cc1/cc1.h
@@ -114,7 +114,8 @@
 enum {
 	NLVAL   = 1 << 0,
 	NCONST  = 1 << 1,
-	NEFFECT = 1 << 2
+	NEFFECT = 1 << 2,
+	NDECAY  = 1 << 3,
 };
 
 /* lexer mode, compiler or preprocessor directive */
--- a/src/cmd/cc/cc1/code.c
+++ b/src/cmd/cc/cc1/code.c
@@ -578,5 +578,6 @@
 	sym = newsym(NS_IDEN, NULL);
 	sym->type = sizettype;
 	sym->u.i = tp->size;
+	DBG("EXPR sizeof %llu", sym->u.i);
 	return constnode(sym);
 }
--- a/src/cmd/cc/cc1/expr.c
+++ b/src/cmd/cc/cc1/expr.c
@@ -8,8 +8,6 @@
 
 #define XCHG(lp, rp, np) (np = lp, lp = rp, rp = np)
 
-static Node *xexpr(void), *xassign(void);
-
 int
 cmpnode(Node *np, TUINT val)
 {
@@ -194,6 +192,7 @@
 
 	switch (tp->op) {
 	case ARY:
+		DBG("EXPR decay ary");
 		tp = tp->type;
 		if (np->op == OPTR) {
 			new = np->left;
@@ -201,14 +200,20 @@
 			new->type = mktype(tp, PTR, 0, NULL);
 			return new;
 		}
+		break;
 	case FTN:
-		new = node(OADDR, mktype(tp, PTR, 0, NULL), np, NULL);
-		if (np->sym && np->sym->flags & (SGLOBAL|SLOCAL|SPRIVATE))
-			new->flags |= NCONST;
-		return new;
+		DBG("EXPR decay function");
+		break;
 	default:
 		return np;
 	}
+
+	new = node(OADDR, mktype(tp, PTR, 0, NULL), np, NULL);
+	if (np->sym && np->sym->flags & (SGLOBAL|SLOCAL|SPRIVATE))
+		new->flags |= NCONST;
+	new->flags |= NDECAY;
+
+	return new;
 }
 
 static Node *
@@ -535,24 +540,33 @@
 address(int op, Node *np)
 {
 	Node *new;
+	Type *tp;
+	Symbol *sym = np->sym;
 
+	if ((np->flags & NDECAY) != 0) {
+		new = np->left;
+		free(np);
+		np = new;
+	}
+	tp = np->type;
+
 	/*
 	 * ansi c accepts & applied to a function name, and it generates
 	 * a function pointer
 	 */
 	if (np->op == OSYM) {
-		if (np->type->op == FTN)
+		if (tp->op == FTN)
 			return decay(np);
-		if (np->type->op == ARY)
+		if (tp->op == ARY)
 			goto dont_check_lvalue;
 	}
 	chklvalue(np);
 
 dont_check_lvalue:
-	if (np->sym && (np->sym->flags & SREGISTER))
+	if (sym && (sym->flags & SREGISTER))
 		errorp("address of register variable '%s' requested", yytext);
-	new = node(op, mktype(np->type, PTR, 0, NULL), np, NULL);
-	if (np->sym && np->sym->flags & (SGLOBAL|SLOCAL|SPRIVATE))
+	new = node(op, mktype(tp, PTR, 0, NULL), np, NULL);
+	if (sym && sym->flags & (SGLOBAL|SLOCAL|SPRIVATE))
 		new->flags |= NCONST;
 	return new;
 }
@@ -629,7 +643,7 @@
 		break;
 	case '(':
 		next();
-		np = xexpr();
+		np = expr();
 		expect(')');
 
 		/* do not call to next */
@@ -685,7 +699,7 @@
 	toomany = 0;
 
 	do {
-		arg = xassign();
+		arg = assign();
 		argtype = *targs;
 		if (argtype == ellipsistype) {
 			n = 0;
@@ -725,26 +739,34 @@
 	return node(op, rettype, np, par);
 }
 
-static Node *unary(int);
-
 static Type *
 typeof(Node *np)
 {
+	Node *new;
 	Type *tp;
 
 	if (np == NULL)
 		unexpected();
+	if ((np->flags & NDECAY) != 0) {
+		new = np->left;
+		free(np);
+		np = new;
+	}
 	tp = np->type;
 	freetree(np);
 	return tp;
 }
 
+static Node *cast(void);
+
 static Type *
 sizeexp(void)
 {
 	Type *tp;
 
-	expect('(');
+	if (!accept('('))
+		return typeof(cast());
+
 	switch (yytoken) {
 	case TYPE:
 	case TYPEIDEN:
@@ -751,10 +773,11 @@
 		tp = typename();
 		break;
 	default:
-		tp = typeof(unary(0));
+		tp = typeof(cast());
 		break;
 	}
 	expect(')');
+
 	return tp;
 }
 
@@ -768,7 +791,7 @@
 		switch (yytoken) {
 		case '[':
 			next();
-			rp = xexpr();
+			rp = expr();
 			expect(']');
 			lp = array(decay(lp), rp);
 			break;
@@ -794,10 +817,8 @@
 	}
 }
 
-static Node *cast(int);
-
 static Node *
-unary(int needdecay)
+unary(void)
 {
 	Node *(*fun)(int, Node *), *np;
 	int op;
@@ -812,7 +833,7 @@
 	case '*': op = OPTR;  fun = content;      break;
 	case SIZEOF:
 		next();
-		tp = (yytoken == '(') ? sizeexp() : typeof(unary(0));
+		tp = sizeexp();
 		if (!(tp->prop & TDEFINED))
 			errorp("sizeof applied to an incomplete type");
 		return sizeofnode(tp);
@@ -820,26 +841,24 @@
 	case DEC:
 		op = (yytoken == INC) ? OA_ADD : OA_SUB;
 		next();
-		np = incdec(unary(1), op);
-		goto chk_decay;
+		np = incdec(unary(), op);
+		goto decay;
 	case DEFINED:
 		return defined();
 	default:
 		np = postfix(primary());
-		goto chk_decay;
+		goto decay;
 	}
 
 	next();
-	np = (*fun)(op, cast(op != OADDR));
+	np = (*fun)(op, cast());
 
-chk_decay:
-	if (needdecay)
-		np = decay(np);
-	return np;
+decay:
+	return decay(np);
 }
 
 static Node *
-cast(int needdecay)
+cast(void)
 {
 	Node *tmp, *np;
 	Type *tp;
@@ -846,7 +865,7 @@
 	static int nested;
 
 	if (!accept('('))
-		return unary(needdecay);
+		return unary();
 
 	switch (yytoken) {
 	case TQUALIFIER:
@@ -862,7 +881,7 @@
 		case ARY:
 			error("cast specifies an array type");
 		default:
-			tmp = cast(needdecay);
+			tmp = cast();
 			if ((np = convert(tmp,  tp, 1)) == NULL)
 				error("bad type conversion requested");
 			np->flags &= ~NLVAL;
@@ -872,7 +891,7 @@
 		if (nested == NR_SUBEXPR)
 			error("too many expressions nested by parentheses");
 		++nested;
-		np = xexpr();
+		np = expr();
 		--nested;
 		expect(')');
 		np = postfix(np);
@@ -888,7 +907,7 @@
 	Node *np, *(*fun)(int, Node *, Node *);
 	int op;
 
-	np = cast(1);
+	np = cast();
 	for (;;) {
 		switch (yytoken) {
 		case '*': op = OMUL; fun = arithmetic; break;
@@ -897,7 +916,7 @@
 		default: return np;
 		}
 		next();
-		np = (*fun)(op, np, cast(1));
+		np = (*fun)(op, np, cast());
 	}
 }
 
@@ -1040,7 +1059,7 @@
 		Node *ifyes, *ifno, *np;
 
 		cond = exp2cond(cond, 0);
-		ifyes = xexpr();
+		ifyes = expr();
 		expect(':');
 		ifno = ternary();
 		np = chkternary(ifyes, ifno);
@@ -1049,8 +1068,8 @@
 	return cond;
 }
 
-static Node *
-xassign(void)
+Node *
+assign(void)
 {
 	Node *np, *(*fun)(int , Node *, Node *);
 	int op;
@@ -1069,7 +1088,7 @@
 		case AND_EQ: op = OA_AND;  fun = integerop;  break;
 		case XOR_EQ: op = OA_XOR;  fun = integerop;  break;
 		case OR_EQ:  op = OA_OR;   fun = integerop;  break;
-		default: return np;
+		default: return simplify(np);
 		}
 		chklvalue(np);
 		np->flags |= NEFFECT;
@@ -1078,23 +1097,21 @@
 	}
 }
 
-static Node *
-xexpr(void)
+Node *
+expr(void)
 {
 	Node *lp, *rp;
 
-	lp = xassign();
-	while (accept(',')) {
-		rp = xassign();
+	lp = assign();
+	if (!accept(','))
+		return lp;
+
+	do {
+		rp = assign();
 		lp = node(OCOMMA, rp->type, lp, rp);
-	}
-	return lp;
-}
+	} while (accept(','));
 
-Node *
-assign(void)
-{
-	return simplify(xassign());
+	return simplify(lp);
 }
 
 Node *
@@ -1113,17 +1130,11 @@
 }
 
 Node *
-expr(void)
-{
-	return simplify(xexpr());
-}
-
-Node *
 condexpr(int neg)
 {
 	Node *np;
 
-	np = exp2cond(xexpr(), neg);
+	np = exp2cond(expr(), neg);
 	if (np->flags & NCONST)
 		warn("conditional expression is constant");
 	return simplify(np);
--- a/src/cmd/cc/cc1/stmt.c
+++ b/src/cmd/cc/cc1/stmt.c
@@ -156,9 +156,12 @@
 
 	emit(OBLOOP, NULL);
 	emit(OLABEL, begin);
+
 	stmt(lbreak, lcont, lswitch);
 	expect(WHILE);
 	np = condition(NONEGATE);
+	expect(';');
+
 	emit(OLABEL, lcont);
 	emit(OBRANCH, begin);
 	emit(OEXPR, np);
--- /dev/null
+++ b/tests/cc/execute/0209-dowhile.c
@@ -1,0 +1,9 @@
+int
+main(void)
+{
+	if (1)
+		do { } while(0);
+	else
+		do { } while(0);
+	return 0;
+}
--- a/tests/cc/execute/0209-flexible.c
+++ /dev/null
@@ -1,17 +1,0 @@
-struct str {
-	int a;
-	char v[];
-};
-
-int
-main(void)
-{
-	struct str *p;
-	int ary[20];
-
-	p = (struct str *) ary;
-	p->a = 2;
-	p->v[0] = 1;
-
-	return !(p->a + p->v[0] == 3);
-}
--- /dev/null
+++ b/tests/cc/execute/0210-flexible.c
@@ -1,0 +1,17 @@
+struct str {
+	int a;
+	char v[];
+};
+
+int
+main(void)
+{
+	struct str *p;
+	int ary[20];
+
+	p = (struct str *) ary;
+	p->a = 2;
+	p->v[0] = 1;
+
+	return !(p->a + p->v[0] == 3);
+}
--- a/tests/cc/execute/scc-tests.lst
+++ b/tests/cc/execute/scc-tests.lst
@@ -169,7 +169,7 @@
 0176-macro.c
 0177-literal.c [TODO]
 0178-include.c
-0179-sizeof.c [TODO]
+0179-sizeof.c
 0180-incomplete.c
 0181-stringize.c
 0182-voidcast.c
@@ -199,4 +199,5 @@
 0206-initializer.c
 0207-structcb.c
 0208-sizeof.c
-0209-flexible.c
+0209-dowhile.c
+0210-flexible.c