aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2025-12-15 19:47:43 +0100
committerlemon <lsof@mailbox.org>2025-12-15 19:47:43 +0100
commitadea4038e6aa8603aa14283375b31366501ed7ee (patch)
treef7f80774c328ce6f58c427d26d307eb1bb43c857
parentcb83b9e05b4a704cc6127e087917a87af8c97be1 (diff)
lex: loop with goto instead of tail recursion
This uncovered a edgecase with loops and lifetime construction in regalloc!
-rw-r--r--c/lex.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/c/lex.c b/c/lex.c
index 026a78b..2f33fc7 100644
--- a/c/lex.c
+++ b/c/lex.c
@@ -1768,6 +1768,7 @@ lex(struct lexer *lx, struct token *tk_)
struct token tkx[1], *tk;
int t;
+Begin:
assert(tk_ != &lx->peektok);
tk = tk_ ? tk_ : tkx;
if (lx->peektok.t) {
@@ -1778,10 +1779,9 @@ lex(struct lexer *lx, struct token *tk_)
if (lx->macstk) {
if (!advancemacro(lx, tk))
- return lex(lx, tk_);
+ goto Begin;
return tk->t;
}
-
bool linebegin = 1,
skip = nppcnd ? ppcndstk[nppcnd-1].cnd != PPCNDTRUE : 0;
enum directive lastcmd = 0;
@@ -1789,7 +1789,7 @@ lex(struct lexer *lx, struct token *tk_)
while ((t = lex0(lx, tk)) == '\n') linebegin = 1;
if (t == '#' && linebegin) {
if (lex0(lx, tk) == '\n') { }
- else if (tk->t == TKNUMLIT || isppident(*tk)) {
+ else if (tk->t == TKNUMLIT || isppident(*tk)) {
lastcmd = tk->t == TKNUMLIT ? PPLINE : findppcmd(tk);
if (nppcnd == lx->nppcnd0) lx->inclguard = NULL;
if (!skip) {
@@ -1844,9 +1844,10 @@ lex(struct lexer *lx, struct token *tk_)
} else {
lx->firstdirective = 0;
linebegin = 0;
- if (skip && tk->t != TKEOF) continue;
+ if (skip && tk->t != TKEOF)
+ continue;
if (tryexpand(lx, tk))
- return lex(lx, tk_);
+ goto Begin;
if (t == TKEOF && nppcnd && ppcndstk[nppcnd-1].filedepth == includedepth) {
struct span span = { ppcndstk[nppcnd-1].ifspan };
error(&span, "#if is not matched by #endif");
@@ -1857,7 +1858,7 @@ lex(struct lexer *lx, struct token *tk_)
markfileonce(lx->fileid, lx->inclguard);
}
struct lexer *sv = lx->save;
- memcpy(lx, lx->save, sizeof *lx);
+ memcpy(lx, sv, sizeof *lx);
free(sv);
--includedepth;
linebegin = 1;
@@ -2041,7 +2042,7 @@ addpredefmacros(struct arena **tmparena)
lx->tmparena = tmparena;
lx->chrbuf0 = countof(lx->chrbuf);
lx->firstdirective = 1;
- while (!lx->eof) lex(lx, NULL);
+ while (lex(lx, NULL) != TKEOF) ;
}
}