shithub: scc

Download patch

ref: 5be6d06570908e1574813c3f9b0f0f6d8a7cc34b
parent: 1c759c3cd3d169a1c58fd40b3b95d5766747accf
author: Roberto E. Vargas Caballero <[email protected]>
date: Thu Apr 24 12:21:17 EDT 2014

Fix stmt() when expression statements

The 'goto repeat' have to be followed only in label cases,
because in other case it is impossible to have a expression
which begins with IDEN.

--- a/code.c
+++ b/code.c
@@ -169,7 +169,8 @@
 void
 emitexp(Node *np)
 {
-	(*np->code)(np);
+	if (np)
+		(*np->code)(np);
 	putchar('\n');
 }
 
--- a/expr.c
+++ b/expr.c
@@ -56,7 +56,7 @@
 	*p2 = np2;
 }
 
-static Node *
+Node *
 eval(Node *np)
 {
 	if (!ISNODECMP(np))
@@ -436,7 +436,6 @@
 		next();
 		np = expr();
 		expect(')');
-	case ';':
 		break;
 	default:
 		error("unexpected '%s'", yytext);
--- a/stmt.c
+++ b/stmt.c
@@ -8,7 +8,7 @@
 Symbol *curfun;
 
 extern Node *convert(Node *np, Type *tp1, char iscast);
-extern Node * iszero(Node *np);
+extern Node *iszero(Node *np), *eval(Node *np);
 static void stmt(Symbol *lbreak, Symbol *lcont, Symbol *lswitch);
 
 static Symbol *
@@ -131,9 +131,13 @@
 	Type *tp = curfun->type->type;
 
 	expect(RETURN);
-	np = expr();
+	np  =  (yytoken == ';') ? NULL : eval(expr());
 	expect(';');
-	if (np->type != tp) {
+	if (!np) {
+		if (tp != voidtype)
+			warn(1, "function returning non void returns no value");
+		tp = voidtype;
+	} else if (np->type != tp) {
 		if (tp == voidtype)
 			warn(1, "function returning void returns a value");
 		else if ((np = convert(np, tp, 0)) == NULL)
@@ -216,7 +220,11 @@
 	case BREAK:    Break(lbreak); break;
 	case CONTINUE: Continue(lcont); break;
 	case GOTO:     Goto(); break;
-	case IDEN:     if (ahead() == ':') Label(); goto repeat;
+	case IDEN:
+		if (ahead() == ':') {
+			Label();
+			goto repeat;
+		}
 	default:       stmtexp(); break;
 	}
 }