fix(extract): drop cgo's import "C" pseudo-package - #1931
Open
ilyabrykau-orca wants to merge 1 commit into
Open
Conversation
`import "C"` is not an import: "C" is reserved by go/build and no package with that path can exist — it only tells the toolchain to compile the preceding comment as C. cbm emitted it as an ordinary import, so the import resolver fell through to its symbol-name fallback (cbm_pipeline_resolve_import_node Strategy 3, pass_pkgmap.c), matched the literal name "C" against every project node called C, and picked the lexicographically smallest one. Measured on a real Go+C repo: all 27 files carrying `import "C"` pointed their IMPORTS edge at the same unrelated `C` member of a test helper — 27 false edges, and 27 files whose import map named a package that does not exist. Skip the spec in parse_go_import_spec. Node counts are unchanged and the file's real imports are untouched; only the false edge disappears (a 3-file fixture goes 22 edges -> 21, 14 nodes -> 14; the real repo goes 27 -> 0 such edges). Reproduce-first: go_cgo_pseudo_import_dropped is RED without the extractor change (the "C" import is still in imports[]) and GREEN with it, while still asserting the file's real `fmt` import survives. Signed-off-by: Ilya Brykau <ilya.brykau@orca.security>
|
Thanks for opening this — it has been seen, and it is queued. This note is automated, but it is not a brush-off: it exists so you know where your PR stands instead of having to guess from silence. Current review status: working through a backlog. What that means for this PR, concretely:
Things that will genuinely speed it up whenever review does happen:
If this fixes a bug, a reproduction we can run is worth more than a description of the symptom. Thanks for contributing, and sorry in advance for the wait. |
ilyabrykau-orca
added a commit
to ilyabrykau-orca/codebase-memory-mcp
that referenced
this pull request
Aug 30, 2026
A Go import path names a package - never a function, method, field or another language's build target. Strategy 1 resolves every correct Go import (module path -> the package's Folder node); when it misses the import is external and the correct result is NO edge. Two name-guess fallbacks violated that: - Strategy 3's language-agnostic symbol-name fallback matched the path's last segment against any project definition of the same simple name and returned the lexicographically smallest survivor: import "os/exec" bound a test harness's exec() method (52 edges on the measured repo), two imports bound a Function extracted from a Makefile. 89 of 2295 Go IMPORTS edges (3.9%) were false; 27 of those are the import "C" case (DeusData#1926/DeusData#1931), the remaining 62 this. - Strategy 1b's sibling-file resolution admits symbol labels through import_targetable_label, re-creating the same bug one directory closer: with Strategy 3 gated, the field census still bound one os/exec import to a same-package exec() method. Gate both on the importing file's language through a new pure predicate, cbm_import_symbol_fallback_allowed(): false for Go, true for everything else - member-importing languages (Python, Java, Rust use crate::ops::helper) legitimately need the symbol fallback, and build/markup grammars (SCSS partials, Meson subdir, Pony use) the sibling one. Strategies 1, 2 and 4 are untouched. Reproduce-first test ei_go_import_never_binds_symbol asserts the IMPORTS relation EXACTLY (an internal package import stays; neither the cross-package nor the same-package decoy may be bound): RED count=2 expected==1 before each gate, GREEN after. Adds ei_edge_count_is, the exact-count sibling of ei_edge_present, since a floor cannot catch a fabricated extra edge. Field-validated on a real ~1150-file Go+C repo: Go IMPORTS by target label went Folder 2206 / Method 85 / Function 4 on main to Folder 2206 / Method 0 / Function 0 with the fix; all 2206 correct package-Folder edges survive. Fixes DeusData#1934 Signed-off-by: Ilya Brykau <ilya.brykau@orca.security>
This was referenced Aug 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1926
Problem
import "C"is not an import."C"is reserved bygo/build; no package with thatimport path can exist. The clause only tells the Go toolchain to compile the
immediately preceding comment block as C.
The Go import parser treated it as an ordinary import spec, so it reached
cbm_pipeline_resolve_import_node(), fell through Strategy 1 (no module resolves) andStrategy 2 (no namespace map), and landed in the Strategy 3 symbol-name fallback
(
src/pipeline/pass_pkgmap.c:1904-1998). That looks up every project node namedCandreturns the targetable candidate with the lexicographically smallest qualified name.
Measured on a real Go+C repository (~1150 Go files): all 27 files carrying
import "C"pointed theirIMPORTSedge at the same unrelatedCmember of a testhelper — 27 false edges, and 27 files whose import map named a package that cannot
exist. Which symbol gets hijacked is decided by a lexicographic tie-break, so it moves
as the repo grows.
Change
internal/cbm/extract_imports.c,parse_go_import_spec()— skip the spec when theimport path is exactly
"C", before the import is pushed. Go-specific knowledge belongsin the Go import parser rather than in the language-agnostic resolver, and dropping it at
extraction also keeps the pseudo-package out of the file's import map used by call
resolution.
Effect
Nodes are unchanged and the file's real imports are untouched; only the false edge
disappears.
IMPORTSwithlocal_name = 'C'Test
tests/test_extraction.c—go_cgo_pseudo_import_dropped.Reproduce-first: RED without the extractor change —
GREEN with it —
319 passed.The test also asserts the same file's real
fmtimport survives, so the fix cannotregress into dropping the whole import block.
Checks
scripts/test.sh --suites extraction— 319 passed, 0 failed.clang-formatclean on both edited hunks.scripts/lint.shcould not complete locally:clang-tidyandcppcheckare notinstalled on this machine. Relying on CI for those two legs.