diff options
| author | 2026-04-19 08:56:51 +0200 | |
|---|---|---|
| committer | 2026-04-19 09:04:00 +0200 | |
| commit | 0856091ac4f17ca9c89a2cb9bd17c54998676abf (patch) | |
| tree | 7d823fd839aa89ddd8aa24675e149e72b6597c48 | |
| parent | cf38747fb3e910160f8f5d7b8c6b32fc3f00ac26 (diff) | |
c: error for statement expression outside function
| -rw-r--r-- | src/c.c | 19 |
1 files changed, 15 insertions, 4 deletions
@@ -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) */ |