Skip to content

ssa: preserve package identity for unexported methods - #2258

Open
cpunion wants to merge 2 commits into
xgo-dev:mainfrom
cpunion:codex/goroot-unexported-itab-20260801
Open

ssa: preserve package identity for unexported methods#2258
cpunion wants to merge 2 commits into
xgo-dev:mainfrom
cpunion:codex/goroot-unexported-itab-20260801

Conversation

@cpunion

@cpunion cpunion commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

Fixes the shared method-identity root cause behind GOROOT fixedbugs/issue24693.go.

Summary

  • qualify promoted unexported method symbols when their declaring package differs from the receiver package, preventing wrapper and ABI method collisions
  • select interface method slots with the Go-compatible package-qualified method identity instead of comparing the spelling alone
  • add the review counterexample as a real multi-package build-and-run regression test, update affected ABI goldens, and remove the Go 1.26 xfail

Tests

  • go test ./ssa -count=1 -timeout=20m
  • go test ./cl -run "^TestRunAndTestFromTestgo/(abimethod|interface|embedunexport-1598)$" -count=1
  • go test ./internal/build -run "^TestBuildPreservesUnexportedMethodIdentity$" -count=1
  • targeted SSA and multi-package regression tests with Go 1.24.11 and Go 1.25.0
  • Go 1.26.5 GOROOT fixedbugs/issue24693.go with an empty xfail configuration
  • new MethodSymbolName and iMethodOf branches are each covered at 100%

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review summary

This is a well-targeted, correct fix. Qualifying an unexported method name with its declaring package path when the receiver package differs (MethodSymbolName) properly preserves Go's package-scoped identity for unexported methods, and the iMethodOf switch from bare-name to types.Id(pkg, name) comparison matches Go's interface-method identity semantics. Both symbol-producing sites (cl/import.go funcName and ssa/abitype.go abiUncommonMethods) route names through the same MethodSymbolNameFuncName pipeline and normalize via PathOf, so definition and reference symbols stay in sync. Test coverage is strong: unit tests for both MethodSymbolName and iMethodOf, plus an end-to-end fixture reproducing the collision, and the corresponding xfail.yaml entry (fixedbugs/issue24693.go) is correctly removed. The unchecked assertions (m.Obj().(*types.Func) on method-set selections, comma-ok elsewhere) are safe.

No blocking issues. Reviewers converged on minor/maintainability observations only.

Findings (non-blocking)

  • ssa/interface.go:53 — removed // TODO(xsw): check signature. The removal looks intentional (interface method names are unique within an interface, so a signature check is unnecessary for correctness). Confirming this was an obsolete-cleanup rather than dropping a still-relevant concern.
  • Performance (informational, not a concern): iMethodOf now computes types.Id(m.Pkg(), m.Name()) per interface method, which allocates one string per method for unexported names (types.Id is allocation-free for exported names). Bounded and correct-by-design for a compiler codegen path; no change needed.

See inline comments for the two maintainability notes worth a short code comment.

Comment thread ssa/type.go
Comment thread cl/import.go
@codecov

codecov Bot commented Aug 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown

LLGo baseline benchmarks

4d95cbf1d2b4 | workflow run | long-term charts

Program measurements

Platform Workload File size vs main Build vs main Run vs main
Linux cprintf 18544 B new 352.352 ms new 1.366 ms new
Linux fmtprintf 2217608 B new 3.296 s new 2.746 ms new
Linux println 71504 B new 355.001 ms new 1.747 ms new
macOS cprintf 84672 B new 300.827 ms new 2.662 ms new
macOS fmtprintf 2361520 B new 3.138 s new 19.318 ms new
macOS println 125712 B new 304.630 ms new 3.120 ms new
Core language and compiler benchmarks
Platform Benchmark ns/op vs main
Linux BenchmarkLookupPCRandom 12.260 ns/op new
Linux BenchmarkMergeCompilerFlags 144.400 ns/op new
Linux BenchmarkMergeLinkerFlags 93.910 ns/op new
Linux BenchmarkChannelBuffered 37.560 ns/op new
Linux BenchmarkChannelHandoff 23972 ns/op new
Linux BenchmarkDefer 43.740 ns/op new
Linux BenchmarkDirectCall 1.758 ns/op new
Linux BenchmarkGlobalRead 1.758 ns/op new
Linux BenchmarkGlobalWrite 2.811 ns/op new
Linux BenchmarkGoroutine 31683 ns/op new
Linux BenchmarkInterfaceCall 8.798 ns/op new
Linux BenchmarkRuntimeGetG 2.463 ns/op new
macOS BenchmarkLookupPCRandom 10.730 ns/op new
macOS BenchmarkMergeCompilerFlags 104.200 ns/op new
macOS BenchmarkMergeLinkerFlags 77.030 ns/op new
macOS BenchmarkChannelBuffered 24.310 ns/op new
macOS BenchmarkChannelHandoff 9474 ns/op new
macOS BenchmarkDefer 31.960 ns/op new
macOS BenchmarkDirectCall 1.136 ns/op new
macOS BenchmarkGlobalRead 1.029 ns/op new
macOS BenchmarkGlobalWrite 1.303 ns/op new
macOS BenchmarkGoroutine 28602 ns/op new
macOS BenchmarkInterfaceCall 4.702 ns/op new
macOS BenchmarkRuntimeGetG 2.612 ns/op new

No main baseline exists yet; all metrics are marked new.

Warning

  • The rendered benchmark data could not be pushed.

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