Skip to content

C/C++ parser: fix 11 finder bugs#114

Open
gadievron wants to merge 4 commits into
masterfrom
pr/c-parser
Open

C/C++ parser: fix 11 finder bugs#114
gadievron wants to merge 4 commits into
masterfrom
pr/c-parser

Conversation

@gadievron

Copy link
Copy Markdown
Collaborator

C/C++ parser: fix 11 finder bugs

Local-only branch pr/c-parser off master 368b559. One of a coordinated 7-PR set fixing parser/reachability bugs found by the OpenAnt finder. File-disjoint from the other 6 PRs (no merge collision; any order).

Addresses 12 finder bug-ids (11 distinct fixes; 1 ride a same-PR canonical).

Bugs fixed

  • [13] c-builtin_filter_leak-234 (c/builtin_filter_leak) — genuinely-new (no prior logged entry)
  • [14] c-metadata-260-dtor (c/metadata_correctness) — genuinely-new (no prior logged entry)
  • [15] c-metadata-259-ctor (c/metadata_correctness) — genuinely-new (no prior logged entry)
  • [29] c-schema_field_drift-237-isinline (c/schema_field_drift) — genuinely-new (no prior logged entry)
  • [30] c-namespace_dispatch-265-virtual (c/namespace_dispatch) — genuinely-new (no prior logged entry)
  • [32] c-metadata-386-structmember (c/metadata_correctness) — genuinely-new (no prior logged entry)
  • [33] c-extraction_gap-368-lambda (c/extraction_gap) — genuinely-new (no prior logged entry)
  • [35] c-extraction_gap-148-operator (c/extraction_gap) — genuinely-new (no prior logged entry)
  • [38] c-namespace_dispatch-386-staticcall (c/namespace_dispatch) — duplicate of [32] in this PR; closed by the same fix (no separate change)
  • [39] c-extraction_gap-152-template (c/extraction_gap) — genuinely-new (no prior logged entry)
  • [40] c-metadata-418-nsfreefunc (c/metadata_correctness) — genuinely-new (no prior logged entry)
  • [51] c-namespace_dispatch-246-membercall (c/namespace_dispatch) — genuinely-new (no prior logged entry)

Dedup status (independent + judge, from raw)

11 genuinely-new · 0 duplicate-of-curated (cross-ref above) · 0 covered-by-curated · 1 intra-PR-duplicate. All re-confirmed STILL PRESENT on pristine master 368b559 (git show 368b559:).

Tests

Verified GREEN in isolation off pristine 368b559: 50 passed (tests/parsers/c/). New per-bug regression tests + a test_<lang>_schema_completeness.py field-contract guard.

Notes

  • TDD per bug (RED→GREEN); independent + judge verified each fix from raw against master.
  • No behavior change outside the listed parser(s).

🤖 Generated with Claude Code

gadievron added 4 commits June 9, 2026 23:31
…eck (BUG-NEW 13)

Local-only finder-fixes-54 (base master 368b559). TDD; 6 tests in the new
tests/parsers/c/test_call_graph_builder_u*.py. Judge (vs prepared
recommendation, independent re-derivation from raw): AGREE / SHIP-AS-IS.
CM-B builtin pre-check scoped SAME-FILE (judge-confirmed: no global cross-file
fallback; genuine-builtin non-link pinned by a negative test). Combined parser
suite: 70 passed, 10 skipped.

Local-only; not pushed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

(cherry picked from commit ef1a3f91f163547a7652132f65613bb1be56c973)
…/operator/template/ns (BUG-NEW 14,15,32,33,35,39,40)

Local-only finder-fixes-54 (base 368b559). 8 tests.
struct_specifier/union_specifier branches mirror class_specifier (closes [32] AND the
[38] static-call dup — VERIFIED: Helper::compute resolves); ctor/dtor on unqualified
leaf; lambda_expression; operator_name; template args in func_id (g<int>!=g);
namespace-qualifier vs class-qualifier (namespaced free fn class_name=None).
Judge+probe: AGREE / SHIP-AS-IS. Full parser suite 131 passed, 10 skipped.
Local-only; not pushed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

(cherry picked from commit e360860ceac539a3d1df0f5068faf560e3e9c6c2)
…G-NEW 29)

Local-only finder-fixes-54 (base master 368b559). The C extractor produces
func_data['is_inline'] but create_unit dropped it from unit metadata (and the
parallel generate_analyzer_output dropped 'isInline'). Carry it in both, matching
the is_static/is_exported convention.

Adds RF-1 field-contract guard tests/parsers/c/test_c_schema_completeness.py:
an explicit producer-key -> dotted-unit-location MAP (+ snake->camel analyzer
map) that round-trips each contracted field, so future drops fail automatically;
plus a self-check pinning the drift-prone key in the map. 5 tests; c+php
parser suites pass.

Judge (vs prepared recommendation): AGREE / SHIP-AS-IS; RF-1 realized as the
sound field-contract MAP (not a key-superset). Independent+judge concurred.

Local-only; not pushed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

(cherry picked from commit 5eece7512f6872d878039e4866a32d13d4311a86)
…erited dispatch

Adds the local-decl type-inference machinery that was MISSING for these two
deferred bugs (judge-confirmed last time they couldn't be a resolver tweak).
10 tests; full c suite 50 passed (no regression of the 9 committed c bugs).

[51] member-dispatch (sound, same-file): preserve the receiver
(_extract_call_name_and_receiver); new _extract_local_var_types (varname->type
from declaration nodes incl. pointer/init/reference declarators); methods_by_class
index; receiver-type-aware _resolve_member_call resolves w.compute()/w->compute()
to Type::compute when the receiver's local-declared type defines it same-file —
else FALLS BACK to base-name resolution (no false edge when type unknown).

[30] virtual/inherited dispatch (static-declared-type FLOOR + inheritance walk):
function_extractor now extracts base classes (_extract_base_classes walks
base_class_clause -> class_bases index); _resolve_member_call does a cycle-guarded
BFS UP the base chain, resolving to the first ancestor that defines the method.
Base* b; b->compute() links ONLY Base::compute (the static type's method) — derived
overrides are the DOCUMENTED non-goal (over-approximation = false edges). Override
stops the walk; unknown/no-definer -> None.

Precision negatives all pass (unknown receiver, free fn unchanged, two-class
disambiguation, override-stops-walk, no-ancestor, inheritance cycle). Independent +
judge verified SOUND from raw; no false edge introduced vs prior behavior. One
pre-existing same-file same-name-cross-namespace mislink is unchanged by this fix
(documented optional follow-up). go/python tree changes are separate (already committed).
Local-only; not pushed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

(cherry picked from commit e55be766db832831a716c3c97509f9af9d103d88)
@gadievron

Copy link
Copy Markdown
Collaborator Author

Merge-order note (not a defect — flagging for landing order)

Most delicate overlap in the set. call_graph_builder.py vs #84: #84 makes _extract_call_name decline field_expression (so obj->m() never wires to an unrelated free function). This PR adds member dispatch that needs the field name. Union: recover the member name in _extract_call_name_and_receiver and resolve it only via typed/same-file member dispatch — preserving #84's "no free-function edge from a member call" guarantee. Keep this PR's callback-arg edges too. (function_extractor.py also overlaps #77 — both anchor on path components; either ordering is fine.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant