Skip to content

Commit 46bb2a5

Browse files
committed
fix 3 bugs, orelse block defer bypass, raw string #if 0 desync, O(N*K) noreturn tagging
1 parent 2ec6a01 commit 46bb2a5

File tree

2 files changed

+24
-9
lines changed

2 files changed

+24
-9
lines changed

parse.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1829,8 +1829,10 @@ static Token *tokenize(File *file) {
18291829
// Scan file-scope tokens for _Noreturn, noreturn, [[noreturn]],
18301830
// or __attribute__((noreturn)) / __attribute__((__noreturn__)).
18311831
// When a noreturn specifier is found before a function declaration,
1832-
// tag all occurrences of that function name with TT_NORETURN_FN.
1832+
// collect the function name into a hashmap, then do a single O(N)
1833+
// pass to tag all occurrences (replaces prior O(N*K) inner loop).
18331834
{
1835+
HashMap nr_map = {0};
18341836
for (Token *t = first; t && t->kind != TK_EOF; t = tok_next(t)) {
18351837
bool is_noreturn = false;
18361838
Token *scan_start = t;
@@ -1914,14 +1916,19 @@ static Token *tokenize(File *file) {
19141916
}
19151917
}
19161918
if (!fn_name) continue;
1919+
hashmap_put(&nr_map, tok_loc(fn_name), fn_name->len, (void *)1);
1920+
}
19171921

1918-
// Tag all occurrences of this function name with TT_NORETURN_FN
1922+
// Single O(N) pass to tag all occurrences of noreturn function names
1923+
if (nr_map.used > 0) {
19191924
for (Token *s = first; s && s->kind != TK_EOF; s = tok_next(s)) {
1920-
if (s->kind == TK_IDENT && tok_name_eq(s, fn_name) &&
1921-
!(tok_idx(s) >= 1 && (token_pool[tok_idx(s) - 1].tag & TT_MEMBER)))
1925+
if (s->kind == TK_IDENT &&
1926+
!(tok_idx(s) >= 1 && (token_pool[tok_idx(s) - 1].tag & TT_MEMBER)) &&
1927+
hashmap_get(&nr_map, tok_loc(s), s->len))
19221928
s->tag |= TT_NORETURN_FN;
19231929
}
19241930
}
1931+
free(nr_map.buckets);
19251932
}
19261933

19271934
return first;

prism.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4449,6 +4449,8 @@ static Token *validate_defer_statement(Token *tok, bool in_loop, bool in_switch,
44494449
if (act && match_ch(act, ';'))
44504450
error_tok(s, "expected statement after 'orelse'");
44514451
validate_defer_control_flow(act, in_loop, in_switch);
4452+
if (act && match_ch(act, '{'))
4453+
validate_defer_statement(act, in_loop, in_switch, depth + 1);
44524454
break;
44534455
}
44544456
}
@@ -5453,11 +5455,11 @@ static void collect_source_defines(const char *input_file) {
54535455
char *rd = NULL;
54545456
if (has_unclosed_block_comment(p, &rd)) {
54555457
in_block_comment = true;
5456-
} else if (rd) {
5458+
} else if (rd && cond_depth == 0) {
54575459
in_raw_string = true;
54585460
raw_delim = rd;
54595461
raw_delim_len = (int)strlen(rd);
5460-
}
5462+
} else free(rd);
54615463
}
54625464
continue;
54635465
}
@@ -5484,18 +5486,23 @@ static void collect_source_defines(const char *input_file) {
54845486
char *rd = NULL;
54855487
if (has_unclosed_block_comment(p, &rd))
54865488
in_block_comment = true;
5487-
else if (rd) { in_raw_string = true; raw_delim = rd; raw_delim_len = (int)strlen(rd); }
5489+
else if (rd && cond_depth == 0) { in_raw_string = true; raw_delim = rd; raw_delim_len = (int)strlen(rd); }
5490+
else free(rd);
54885491
goto check_continuation;
54895492
}
54905493
goto have_hash;
54915494
}
54925495
// Non-preprocessor, non-blank line — scan for mid-line
54935496
// block comment or raw string that spans subsequent lines.
5497+
// Raw string detection suppressed inside #if/#ifdef blocks:
5498+
// the C preprocessor doesn't lex tokens in dead branches,
5499+
// so R"(...)" containing #endif would desync nesting.
54945500
{
54955501
char *rd = NULL;
54965502
if (has_unclosed_block_comment(p, &rd))
54975503
in_block_comment = true;
5498-
else if (rd) { in_raw_string = true; raw_delim = rd; raw_delim_len = (int)strlen(rd); }
5504+
else if (rd && cond_depth == 0) { in_raw_string = true; raw_delim = rd; raw_delim_len = (int)strlen(rd); }
5505+
else free(rd);
54995506
}
55005507
goto check_continuation;
55015508
}
@@ -5729,7 +5736,8 @@ static void collect_source_defines(const char *input_file) {
57295736
char *rd = NULL;
57305737
if (has_unclosed_block_comment(line, &rd))
57315738
in_block_comment = true;
5732-
else if (rd) { in_raw_string = true; raw_delim = rd; raw_delim_len = (int)strlen(rd); }
5739+
else if (rd && cond_depth == 0) { in_raw_string = true; raw_delim = rd; raw_delim_len = (int)strlen(rd); }
5740+
else free(rd);
57335741
}
57345742
}
57355743
}

0 commit comments

Comments
 (0)