Skip to content

x/tools/go/ssa: generic methods with empty bodies panic with SanityCheckFunctions #73594

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
eliasnaur opened this issue May 3, 2025 · 2 comments
Assignees
Labels
Tools This label describes issues relating to any tools in the x/tools repository.
Milestone

Comments

@eliasnaur
Copy link
Contributor

eliasnaur commented May 3, 2025

Go version

go version go1.24.2 darwin/arm64

Output of go env in your module/workspace:

AR='ar'
CC='clang'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='clang++'
GCCGO='gccgo'
GO111MODULE=''
GOARCH='arm64'
GOARM64='v8.0'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/Users/a/Library/Caches/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/Users/a/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/9c/t7b8z6m93sxgr4m4m4kbvllw0000gn/T/go-build2808707577=/tmp/go-build -gno-record-gcc-switches -fno-common'
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMOD='/Users/a/proj/golang-tools/go.mod'
GOMODCACHE='/Users/a/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/a/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/nix/store/fd2s1z3why92qn8w7j6r0xlarikpv27v-go-1.24.2/share/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/Users/a/Library/Application Support/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/nix/store/fd2s1z3why92qn8w7j6r0xlarikpv27v-go-1.24.2/share/go/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.24.2'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

In x/tools, add a test,

% jj diff
diff --git a/go/ssa/builder_test.go b/go/ssa/builder_test.go
index a48723bd2..2a40a200d 100644
--- a/go/ssa/builder_test.go
+++ b/go/ssa/builder_test.go
@@ -1045,6 +1045,7 @@ func TestFixedBugs(t *testing.T) {
        for _, name := range []string{
                "issue66783a",
                "issue66783b",
+               "issueXXXXX",
        } {

                t.Run(name, func(t *testing.T) {
diff --git a/go/ssa/testdata/fixedbugs/issueXXXXX.go b/go/ssa/testdata/fixedbugs/issueXXXXX.go
new file mode 100644
index 000000000..5a7c4ef56
--- /dev/null
+++ b/go/ssa/testdata/fixedbugs/issueXXXXX.go
@@ -0,0 +1,10 @@
+package issueXXXXX
+
+type genericType[T any] struct{}
+
+func (genericType[T]) methodWithoutBody()
+
+func callMethodWithoutBody() {
+       msg := &genericType[int]{}
+       msg.methodWithoutBody()
+}

What did you see happen?

$ go test ./go/ssa
# Name: testdata/a.init
# Package: testdata/a
# Synthetic: package initializer
func init():
0:                                                                entry P:0 S:2
        t0 = *init$guard                                                   bool
        if t0 goto 2 else 1
1:                                                           init.start P:1 S:1
        *init$guard = true:bool
        t1 = testdata/b.init()                                               ()
        jump 2
2:                                                            init.done P:2 S:0
        return

# Name: testdata/a.A
# Package: testdata/a
# Location: /var/folders/9c/t7b8z6m93sxgr4m4m4kbvllw0000gn/T/TestNoIndirectCreatePackage2015203071/001/a/a.go:5:6
func A():
0:                                                                entry P:0 S:0
        t0 = testdata/b.B{}:testdata/b.B.C [#0]                    testdata/c.C
        t1 = (testdata/c.C).F(t0)                                            ()
        return

# Name: (testdata/c.C).F
# Synthetic: from type information (on demand)
# Location: /var/folders/9c/t7b8z6m93sxgr4m4m4kbvllw0000gn/T/TestNoIndirectCreatePackage2015203071/001/c/c.go:4:10
func (testdata/c.C) F():
        (external)

Error: function (issueXXXXX.genericType[int]).methodWithoutBody[int]: function transient field 'subst' is not nil
# Name: (issueXXXXX.genericType[int]).methodWithoutBody[int]
# Synthetic: instance of methodWithoutBody
# Location: /Users/a/proj/golang-tools/go/ssa/testdata/fixedbugs/issueXXXXX.go:5:23
func (genericType[int]) methodWithoutBody[int]():
        (external)

--- FAIL: TestFixedBugs (0.00s)
    --- FAIL: TestFixedBugs/issueXXXXX (0.00s)
panic: SanityCheck failed [recovered]
        panic: SanityCheck failed

goroutine 1257 [running]:
testing.tRunner.func1.2({0x10134bd60, 0x1013c8d20})
        /nix/store/fd2s1z3why92qn8w7j6r0xlarikpv27v-go-1.24.2/share/go/src/testing/testing.go:1734 +0x1ac
testing.tRunner.func1()
        /nix/store/fd2s1z3why92qn8w7j6r0xlarikpv27v-go-1.24.2/share/go/src/testing/testing.go:1737 +0x334
panic({0x10134bd60?, 0x1013c8d20?})
        /nix/store/fd2s1z3why92qn8w7j6r0xlarikpv27v-go-1.24.2/share/go/src/runtime/panic.go:792 +0x124
golang.org/x/tools/go/ssa.mustSanityCheck(0x14003064600, {0x0?, 0x0?})
        /Users/a/proj/golang-tools/go/ssa/sanity.go:48 +0x94
golang.org/x/tools/go/ssa.(*Function).done.func1(0x14003064600)
        /Users/a/proj/golang-tools/go/ssa/func.go:415 +0x19c
golang.org/x/tools/go/ssa.(*Function).done(0x14001ef4fc0?)
        /Users/a/proj/golang-tools/go/ssa/func.go:418 +0x4c
golang.org/x/tools/go/ssa.(*builder).buildFunction(0x1?, 0x14003064600)
        /Users/a/proj/golang-tools/go/ssa/builder.go:2907 +0x114
golang.org/x/tools/go/ssa.(*builder).iterate(0x14001ef4fc0)
        /Users/a/proj/golang-tools/go/ssa/builder.go:2891 +0x2c
golang.org/x/tools/go/ssa.(*Package).build(0x14001272380)
        /Users/a/proj/golang-tools/go/ssa/builder.go:3174 +0xc8
sync.(*Once).doSlow(0x14004db4c60?, 0x14003046c00?)
        /nix/store/fd2s1z3why92qn8w7j6r0xlarikpv27v-go-1.24.2/share/go/src/sync/once.go:78 +0xf0
sync.(*Once).Do(...)
        /nix/store/fd2s1z3why92qn8w7j6r0xlarikpv27v-go-1.24.2/share/go/src/sync/once.go:69
golang.org/x/tools/go/ssa.(*Package).Build(...)
        /Users/a/proj/golang-tools/go/ssa/builder.go:3163
golang.org/x/tools/go/ssa/ssautil.BuildPackage(0x14003042310, 0x14002781a80, 0x14003046c00, {0x14003484958, 0x1, 0x1}, 0x108)
        /Users/a/proj/golang-tools/go/ssa/ssautil/load.go:187 +0x340
golang.org/x/tools/go/ssa_test.TestFixedBugs.func1(0x14002b35a40)
        /Users/a/proj/golang-tools/go/ssa/builder_test.go:1063 +0x188
testing.tRunner(0x14002b35a40, 0x1400304a0c0)
        /nix/store/fd2s1z3why92qn8w7j6r0xlarikpv27v-go-1.24.2/share/go/src/testing/testing.go:1792 +0xe4
created by testing.(*T).Run in goroutine 1254
        /nix/store/fd2s1z3why92qn8w7j6r0xlarikpv27v-go-1.24.2/share/go/src/testing/testing.go:1851 +0x374
FAIL    golang.org/x/tools/go/ssa       1.354s
FAIL

What did you expect to see?

No error.

@gopherbot gopherbot added the Tools This label describes issues relating to any tools in the x/tools repository. label May 3, 2025
@gopherbot gopherbot added this to the Unreleased milestone May 3, 2025
@adonovan
Copy link
Member

adonovan commented May 5, 2025

Thanks for the bug report and test case. Fix pending.

@adonovan adonovan self-assigned this May 5, 2025
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/669955 mentions this issue: go/ssa: clear Function.subst after building bodyless function

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Tools This label describes issues relating to any tools in the x/tools repository.
Projects
None yet
Development

No branches or pull requests

3 participants