aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2026-04-19 08:56:51 +0200
committerlemon <lsof@mailbox.org>2026-04-19 09:04:00 +0200
commit0856091ac4f17ca9c89a2cb9bd17c54998676abf (patch)
tree7d823fd839aa89ddd8aa24675e149e72b6597c48
parentcf38747fb3e910160f8f5d7b8c6b32fc3f00ac26 (diff)
c: error for statement expression outside function
-rw-r--r--src/c.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/src/c.c b/src/c.c
index a87c748..03d74c2 100644
--- a/src/c.c
+++ b/src/c.c
@@ -1005,14 +1005,12 @@ tkprec(int tt)
static Expr initializer(CComp *, Type *ty, enum evalmode ev,
bool globl, enum qualifier qual, internstr name);
-
static void block(CComp *, Ref *stmtexprval, Type *stmtexprty);
static internstr istr__func__, istr_main, istr_memset;
static internstr mkhiddensym(const char *fnname, const char *name, int id);
-
/* parse an expression with the given operator precedence */
/* param ident is a kludge to support block labels without backtracking or extra lookahead
* see stmt() */
@@ -1070,8 +1068,21 @@ Unary:
Span span = tk.span;
Ref val;
ex.t = EIRVALUE;
- block(cm, &val, &ex.ty);
- ex.irref.bits = val.bits;
+ if (!cm->fn) {
+ error(&span, "statement expression not allowed outside function");
+ int bal = 1;
+ do {
+ switch (lex(cm, &tk)) {
+ case '}': --bal; break;
+ case '{': ++bal; break;
+ case TKEOF: bal = 0; break;
+ }
+ } while (bal != 0);
+ ex.ty = mktype(TYINT);
+ } else {
+ block(cm, &val, &ex.ty);
+ ex.irref.bits = val.bits;
+ }
if (expect(cm, ')', NULL)) joinspan(&span.ex, tk.span.ex);
ex.span = span;
} else if (!isdecltok(cm)) { /* (expr) */