fix(parsers/c): guard macro-alias resolution against cyclic #defines#130
fix(parsers/c): guard macro-alias resolution against cyclic #defines#130gadievron wants to merge 1 commit into
Conversation
|
Finding F4 (HIGH). |
322624f to
4058a1c
Compare
_resolve_call recursed on a macro alias target with no visited-set, so a cyclic
function-like #define pair ({"A":"B","B":"A"}) looped A->B->A->... until
RecursionError aborted the entire repository's C call-graph build. Thread an
_alias_chain set through the recursion so a cyclic alias resolves to None.
Stacked on pr/zig-php-generic-anon, whose C-parser rework carries the same
unguarded macro recursion; this layers the cycle guard on top of that signature.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
8e24294 to
080d67d
Compare
|
Rebased onto origin/master (post-release #133 / Wave 1). Conflicts resolved by UNION — both this PR's fix and the Wave-1 parser fixes are preserved; no Wave-1 change reverted (independently judge-verified). Force-pushed with --force-with-lease. Rebased onto the newly-rebased #127 (kept stacked, base pr/zig-php-generic-anon). Merge AFTER #127. C tests green (16). |
|
Closing as already resolved on current master. This fix's behavior shipped via the parser-fix-stack release (#133/#134); confirmed by independent reproduction — the original bug (reconstructed from its bug-pipeline investigation) no longer manifests on master, not merely by line-presence. Part of a full validated sweep of the open-PR corpus. |
fix(parsers/c): guard macro-alias resolution against cyclic #defines
Base:
pr/zig-php-generic-anon· Depends-on: #127 · Type: bug fix · Finding: F4 (HIGH)What
parsers/c/call_graph_builder.py—_resolve_callthreads an_alias_chainvisited-set through its macro-alias recursion, so a cyclic alias resolves to
Noneinstead of recursing forever.Why
macro_aliasesis built from function-like#defines. A cyclic pair —#define A(x) B(x)/#define B(x) A(x)→{"A":"B","B":"A"}— made_resolve_call("A")recurseA→B→A→…with no guard →RecursionError.build_call_graphiterates every function with no try/except, so one poisoneddefine pair aborts the entire repository's C call-graph build (seen on vendored
LLVM in ziglang/zig). A self-alias was already safe via the
resolved_name != call_nameshort-circuit; only 2+ node cycles triggered it.Tests
tests/test_c_macro_alias_cycle.py(new): 2-node cycle, 3-node cycle, self-alias.RecursionError.Upstream coordination
The cyclic-macro recursion is live on master, on the C staging stack (#114/#121),
and on #127 — all unguarded. This guard is non-overlapping with those refactors;
sequence after #127 (or the C stack), re-anchoring onto the post-rework
_resolve_call.Author notes
if resolved_name not in _alias_chain:guard around therecursive
_resolve_call(..., _alias_chain=_alias_chain).#definemacro pairs that crashed the whole-repoparse.
cycle with no arbitrary limit, mirroring the file's other visited guards.