You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
C: a call resolves by exact name onto a static function in another translation unit (4,448 edges on betaflight) #1730
A static function in C is visible only in its own translation unit, but the exact-name strategy accepts it as the target of a call from any other file. When the caller's file has no same-named definition and another file has a static one, the call resolves onto it.
The real target is whatever core.c links against — a non-static usbGetDescriptor elsewhere, a function pointer, a macro — but never that one. When a same-file static of the same name exists the proximity score in findBestMatch picks it, so the wrong edge appears exactly when the caller's file has no definition, which is the case that matters for cross-file navigation.
Scale
On a 2,109-file betaflight tree, of 42,460 cross-file calls/imports edges resolved by exact-match or fuzzy, 4,448 target a function declared static in a file other than the caller's (10%). A typical run of them:
usbd_sdr.c calls those through a descriptor table of function pointers; audio_desc.c, cdc_desc.c, hid_desc.c, … each define their own static get_device_descriptor, and the matcher hands every call to the first file it ranks.
This is the C form of the same defect: a binding that the language makes file-local is admitted as a cross-file candidate. #1720's isSealedModule is deliberately JS/TS-only. In C the signal is per symbol, not per file — the definition's storage class — and the extractor already sees the static specifier on the function_definition, so it could either mark the node (a visibility/isStatic flag) or the resolver could read the definition line as #1720 reads source. Same-file candidates must stay eligible, and a static in a header included by the caller is a genuine same-unit call, which is the one exception to keep in mind.
Correction to the count above. Of the 4,448 cross-file calls onto a static in another file, 4,306 target a static inline in a header — MAVLink's mavlink_msg_*.h / protocol.h — and those are correct edges: a header is textually included, so its static inline exists in every unit that names it and is callable from each. The defect is only a static defined in a translation unit (.c, .cc, …) reached from another file: 145 rows on this tree, the USB descriptor-table shape in the body (and STM32 class sources landing on GD32's usbd_enum.c statics). The 10% figure was counting the header calls; the real share is 0.3%.
#1732 carries the fix with the rule scoped that way (second commit, 42a9267), and a test that keeps the header case.
Verified on Linux against current main (includes merged #1745 / rebase of #1732): the issue repro no longer produces coreRun --calls--> usb_audio.c::usbGetDescriptor.
Activity
fix(resolution): a static in a header is part of every unit that incl…
danusha2345 commentedon Sep 7, 2026
Correction to the count above. Of the 4,448 cross-file calls onto a
staticin another file, 4,306 target astatic inlinein a header — MAVLink'smavlink_msg_*.h/protocol.h— and those are correct edges: a header is textually included, so itsstatic inlineexists in every unit that names it and is callable from each. The defect is only astaticdefined in a translation unit (.c,.cc, …) reached from another file: 145 rows on this tree, the USB descriptor-table shape in the body (and STM32 class sources landing on GD32'susbd_enum.cstatics). The 10% figure was counting the header calls; the real share is 0.3%.#1732 carries the fix with the rule scoped that way (second commit,
42a9267), and a test that keeps the header case.colbymchenry commentedon Sep 8, 2026
Also addressed by #1745 (rebase of #1732). Leaving this issue open for whoever owns C closeout / #1732 coordination — Forge's mandate was #1731.
colbymchenry commentedon Sep 8, 2026
Verified on Linux against current
main(includes merged #1745 / rebase of #1732): the issue repro no longer producescoreRun --calls--> usb_audio.c::usbGetDescriptor.core.ccallsusbGetDescriptor();usb_audio.cdefinesstatic void usbGetDescriptor(void) {}.CodeGraph.init+resolveReferences,coreRunhas nocallsedge onto that static (exact-match no longer admits a TU-localstaticin another.c).__tests__/cross-file-visibility.test.ts— 11 passed (CODEGRAPH_KERNEL=0, Node 22.19), including same-filestatickept and headerstatic inlinekept.Fixed by #1745 (already closed this issue on merge). No duplicate PR.
fix(resolution): a definition its language makes file-local is not a …
fix(resolution): a receiver-less JS/TS call never binds to a method (#…
Merge origin/main (8c04734) into fork/consolidated