Summary
A package can build, link, and run successfully from a forced cold build, then fail to link on the immediately following LLGo package-cache hit. The cached path loses definitions for generic local runtime type descriptors while the synthetic root module still references them from init$abitypes$array.
This is reproducible with build parallelism fixed at one, so it is not explained by concurrent package workers.
Discovered while validating #2296, but reproduced unchanged on main without that PR.
Reproducer
At main commit c454c0e65b7161c833da54643968b06eede93660:
go build -o /tmp/llgo-cache-repro ./cmd/llgo
# Force a serial rebuild while leaving cache publication enabled: PASS.
LLGO_ROOT="$PWD" /tmp/llgo-cache-repro test \
-a -p=1 -count=1 -timeout=5m \
-run "^TestGeneric(Local|Nested)" ./test/go
# Same source and serial build setting, now loading the package cache: link failure.
LLGO_ROOT="$PWD" /tmp/llgo-cache-repro test \
-p=1 -count=1 -timeout=5m \
-run "^TestGeneric(Local|Nested)" ./test/go
The second command reports missing symbols such as:
undefined symbol: *_llgo_github.com/goplus/llgo/test/go.local[string].p7240776
undefined symbol: *_llgo_github.com/goplus/llgo/test/go.local[int].p7240776
undefined symbol: *_llgo_github.com/goplus/llgo/test/go.T[int;int].p7241770
undefined symbol: *_llgo_github.com/goplus/llgo/test/go.T[int;github.com/goplus/llgo/test/go.U[int;int]·3].p7241770
All are referenced by the generated init$abitypes$array in the synthetic main object.
Disabling LLGo package-cache reads and writes makes the same source pass:
LLGO_BUILD_CACHE=off LLGO_ROOT="$PWD" /tmp/llgo-cache-repro test \
-p=1 -count=1 -timeout=5m \
-run "^TestGeneric(Local|Nested)" ./test/go
Additional checks
-a -p=1 followed by -p=1 reproduces on unmodified main.
- A different test selector reproduces the same link failure because the entire
test/go package is linked; running the generic-local tests directly confirms the symbols involved.
- A cold build with
LLGO_BUILD_CACHE=off passes the full focused finalizer and reflect test set.
Expected behavior
The cache-hit build should contain the same ABI type definitions as the cold build and link successfully. Package build parallelism should not change cache correctness.
Environment
- Darwin 25.2.0 arm64
- Go 1.26.5 darwin/arm64
- LLGo
(devel) darwin/arm64
- Homebrew Clang 19.1.7
Workaround
Use LLGO_BUILD_CACHE=off or force every build with -a until cache restoration preserves the synthesized type definitions.
Summary
A package can build, link, and run successfully from a forced cold build, then fail to link on the immediately following LLGo package-cache hit. The cached path loses definitions for generic local runtime type descriptors while the synthetic root module still references them from
init$abitypes$array.This is reproducible with build parallelism fixed at one, so it is not explained by concurrent package workers.
Discovered while validating #2296, but reproduced unchanged on
mainwithout that PR.Reproducer
At
maincommitc454c0e65b7161c833da54643968b06eede93660:The second command reports missing symbols such as:
All are referenced by the generated
init$abitypes$arrayin the synthetic main object.Disabling LLGo package-cache reads and writes makes the same source pass:
Additional checks
-a -p=1followed by-p=1reproduces on unmodifiedmain.test/gopackage is linked; running the generic-local tests directly confirms the symbols involved.LLGO_BUILD_CACHE=offpasses the full focused finalizer and reflect test set.Expected behavior
The cache-hit build should contain the same ABI type definitions as the cold build and link successfully. Package build parallelism should not change cache correctness.
Environment
(devel) darwin/arm64Workaround
Use
LLGO_BUILD_CACHE=offor force every build with-auntil cache restoration preserves the synthesized type definitions.