commit 5be6d06570908e1574813c3f9b0f0f6d8a7cc34b
parent 1c759c3cd3d169a1c58fd40b3b95d5766747accf
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Thu, 24 Apr 2014 16:21:17 +0200
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.
Diffstat:
3 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/code.c b/code.c
@@ -169,7 +169,8 @@ emitsizeof(Node *np)
void
emitexp(Node *np)
{
- (*np->code)(np);
+ if (np)
+ (*np->code)(np);
putchar('\n');
}
diff --git a/expr.c b/expr.c
@@ -56,7 +56,7 @@ typeconv(Node **p1, Node **p2)
*p2 = np2;
}
-static Node *
+Node *
eval(Node *np)
{
if (!ISNODECMP(np))
@@ -436,7 +436,6 @@ primary(void)
next();
np = expr();
expect(')');
- case ';':
break;
default:
error("unexpected '%s'", yytext);
diff --git 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 @@ Return(void)
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 @@ repeat:
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;
}
}