Skip to content

Fix cpp class_start forward-declaration false positive (closes #2011) - #2019

Merged
squid-protocol merged 1 commit into
mainfrom
fix/cpp-class-forward-declaration-2011
Aug 21, 2026
Merged

Fix cpp class_start forward-declaration false positive (closes #2011)#2019
squid-protocol merged 1 commit into
mainfrom
fix/cpp-class-forward-declaration-2011

Conversation

@squid-protocol

Copy link
Copy Markdown
Owner

Summary

Fixes #2011, found during the cpp tri-comparison-ledger-sweep merged in #2015. That
PR fixed the comparison tooling's own tree-sitter walker (which had the identical
lang == "c"-only forward-declaration guard gap as GitGalaxy's own detector.py),
but deliberately left the production detector.py fix filed rather than patched
inline, since a naive copy of C's existing flat lookahead regex is unsafe for cpp.

That decision turned out to have a real, immediate consequence: once the tree-sitter
walker stopped agreeing with GitGalaxy's forward-declaration false positives, main
was left with a standing inconsistency — tests/tree_sitter_accuracy_baseline_cpp.json
still commits the old, both-sides-wrong numbers (real_classes: 171, found_classes: 149), while the actual tree-sitter ground truth now computes 65. Any PR touching cpp
tooling would inherit this as a tree-sitter-accuracy-audit CI failure through no
fault of its own (confirmed: this is what happened while finishing out PR #2015's own
review). This PR closes that gap by actually fixing the underlying bug rather than
leaving main in a broken state.

The bug: GitGalaxy's own class_start regex counted a bare forward declaration
(class AudioStreamPreviewGenerator;, godot/editor_node.h:68 and 83 more of the same
shape in the same file) as if it were a real class definition —
_CLASS_START_REQUIRES_BODY_ANCHOR in detector.py, the exact mechanism that already
guards against this for C, was never extended to cpp.

Why not just copy C's fix: C's existing lookahead (re.search(r"^[^\{;,)=]{0,200}?([\{;,)=])", ...))
stops at the first {/;/,/)/=. C++ multiple inheritance
(class Foo : public A, public B {) hits the comma stop-char before the real {,
falsely excluding a legitimate multi-inheritance class definition — confirmed via
direct regex testing before this fix was written specifically to avoid that
regression.

The fix: _cpp_class_has_body(), a depth-aware scanner (paren/bracket/angle-bracket
tracking, same style as this file's existing _dart_scan_terminator/
_count_top_level_args helpers) that correctly walks through an inheritance clause's
own top-level commas and template args before checking for a real body opener. A
top-level , before any inheritance-list : has been seen is still treated as a
non-definition signal, preserving the pre-existing protection against a type-use in a
declarator list (struct Foo *a, *b;) or a function parameter default
(void f(struct Foo* p = nullptr)).

Also regenerates tests/tree_sitter_accuracy_baseline_cpp.json (class recall 87.1% →
100.0%, both found_classes and extra_classes now correctly reflect zero forward-
declaration false positives) and the tri-comparison ledger/chart/docs/language_status/ cpp.md to record the fix.

Test plan

  • 11 hand-built regression cases for _cpp_class_has_body (forward decl, plain
    definition, single/multi inheritance, templated bases, type-use-in-declarator-
    list, function-parameter-default, final specifier) — all pass
  • Full cpp extraction gauntlet (122 tests) + tests/core_engine/test_detector.py
    (141 tests) + C's own extraction gauntlet (128 tests, confirmed unaffected)
  • python tests/ruff_audit.py --ci / mypy_audit.py --ci — no new findings
  • ruff format --check clean
  • tests/tools/crucible_check.py (full-precision + zero-dependency) against the
    full ~80-repo corpus — zero golden-master diff, confirmed legitimate (not a
    blind spot) via a direct DB query showing the named-class list this fix touches
    dropped from ~95 to 11 for editor_node.h specifically
  • tree_sitter_accuracy_audit.py --lang cpp --ci — passes cleanly against the
    regenerated baseline

🤖 Generated with Claude Code

The tree-sitter walker fix in the previous commit surfaced this as a real CI
regression in tests/tree_sitter_accuracy_baseline_cpp.json (found_classes'
denominator, real_classes, correctly dropped once the walker no longer counted
forward declarations -- exposing that GitGalaxy's own class_start had the
identical bug, previously masked by both sides agreeing on the same wrong
answer). Fixed rather than left filed, since the regression made the gap
impossible to defer further.

A naive copy of C's existing _CLASS_START_REQUIRES_BODY_ANCHOR flat lookahead
(stops at the first {/;/,/)/=) is unsafe for cpp: C++ multiple inheritance
(`class Foo : public A, public B {`) hits the lookahead's own comma stop-char
before the real `{`, falsely excluding a legitimate class definition --
confirmed via direct regex testing before this fix was written.

Fixed instead with _cpp_class_has_body(), a depth-aware scanner (paren/
bracket/angle-bracket, same style as the existing _dart_scan_terminator/
_count_top_level_args helpers) that correctly walks through an inheritance
clause's own top-level commas and template args before checking for a real
body opener. Verified via 11 hand-built regression cases (multi-inheritance,
templated bases, the pre-existing type-use-in-declarator-list protection),
the full 122-test cpp extraction gauntlet, and crucible_check.py against the
full ~80-repo corpus (zero golden-master diff -- confirmed via a direct DB
query that this is because the golden master's audit report only exposes the
raw class_start signal count, not the named-class list this fix touches, not
because the fix is a no-op).

Regenerates the cpp tree-sitter-accuracy baseline (found_classes/real_classes
171->65, both now matching cleanly -- class recall 87.1% -> 100.0%) and the
tri-comparison ledger/chart/docs to reflect the shape no longer reproducing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@squid-protocol
squid-protocol merged commit 2b2dbe4 into main Aug 21, 2026
26 of 27 checks passed
@squid-protocol
squid-protocol deleted the fix/cpp-class-forward-declaration-2011 branch August 21, 2026 14:11
@github-actions

Copy link
Copy Markdown
Contributor

🐦‍⬛ Muninn Security Scan

✅ No security issues found.

🐦‍⬛ Powered by Muninn · Skald Lab

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.

cpp class_start counts forward declarations as real class/struct definitions

1 participant