Skip to content
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

cmd/vet, go/types: go vet crash when using self-recursive anonymous types in constraints #51717

Closed
cr7pt0gr4ph7 opened this issue Mar 16, 2022 · 8 comments
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done. release-blocker Soon This needs to be done soon. (regressions, serious bugs, outages)
Milestone

Comments

@cr7pt0gr4ph7
Copy link

What version of Go are you using (go version)?

$ go version
go version devel go1.19-5fd0ed7aaf Wed Mar 16 07:03:20 2022 +0000

Does this issue reproduce with the latest release?

Yes, with go1.18 linux/amd64.

What did you do?

Running go vet on the following legal Go 1.18 code causes a stack overflow:

package main

type S struct{}

func (_ S) M() {
	// The go vet stackoverflow crash disappears when the following line is removed
	panic("")
}

func F[WL interface{ N(item W) WL }, W any]() {
}

func main() {
}

https://gotipplay.golang.org/p/XWvgmRsOFpy

Additional notes:

  • For some reason, the crash disappears when the panic("") call is removed, or when it is replaced with a call to a locally declared function (e.g. func G() {} or func G(_ string) {}).
  • The code above still builds and runs successfully though, so the issue seems to be related to some parts of go/types only used by go vet, but not by go compile.

What did you expect to see?

A successful execution of go vet.

What did you see instead?

A stack overflow error related to go/types.computeInterfaceTypeSet:

runtime: goroutine stack exceeds 1000000000-byte limit
runtime: sp=0xc020160368 stack=[0xc020160000, 0xc040160000]
fatal error: stack overflow

runtime stack:
runtime.throw({0x6d380d?, 0x88ac00?})
	/usr/local/go/src/runtime/panic.go:992 +0x71
runtime.newstack()
	/usr/local/go/src/runtime/stack.go:1101 +0x5cc
runtime.morestack()
	/usr/local/go/src/runtime/asm_amd64.s:547 +0x8b

goroutine 1 [running]:
go/types.computeInterfaceTypeSet(0x0, 0x0?, 0xc000086a50)
	/usr/local/go/src/go/types/typeset.go:153 +0xc37 fp=0xc020160378 sp=0xc020160370 pc=0x5e6a17
go/types.(*Interface).typeSet(...)
	/usr/local/go/src/go/types/interface.go:28
go/types.(*Interface).NumMethods(...)
	/usr/local/go/src/go/types/interface.go:112
cmd/vendor/golang.org/x/tools/go/types/objectpath.find({0x737a88?, 0xc000087d60?}, {0x735fc0?, 0xc000086a50?}, {0xc001e2c000, 0x2d82c5, 0x34a000})
	/usr/local/go/src/cmd/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go:371 +0x8c5 fp=0xc0201604e0 sp=0xc020160378 pc=0x61a2a5
cmd/vendor/golang.org/x/tools/go/types/objectpath.find({0x737a88?, 0xc000087d60?}, {0x736128?, 0xc000126690?}, {0xc001e2c000, 0x2d82c4, 0x34a000})
	/usr/local/go/src/cmd/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go:387 +0x4a5 fp=0xc020160648 sp=0xc0201604e0 pc=0x619e85
cmd/vendor/golang.org/x/tools/go/types/objectpath.find({0x737a88?, 0xc000087d60?}, {0x736100?, 0xc00009cc48?}, {0xc001e2c000, 0x2d82c1, 0x34a000})
	/usr/local/go/src/cmd/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go:365 +0xe7a fp=0xc0201607b0 sp=0xc020160648 pc=0x61a85a
cmd/vendor/golang.org/x/tools/go/types/objectpath.find({0x737a88?, 0xc000087d60?}, {0x736088?, 0xc00011f1c0?}, {0xc001e2c000, 0x2d82c0, 0x34a000})
	/usr/local/go/src/cmd/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go:342 +0x685 fp=0xc020160918 sp=0xc0201607b0 pc=0x61a065
cmd/vendor/golang.org/x/tools/go/types/objectpath.find({0x737a88?, 0xc000087d60?}, {0x735fc0?, 0xc000087f40?}, {0xc001e2c000, 0x2d82bd, 0x34a000})
	/usr/local/go/src/cmd/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go:377 +0xa65 fp=0xc020160a80 sp=0xc020160918 pc=0x61a445
cmd/vendor/golang.org/x/tools/go/types/objectpath.find({0x737a88?, 0xc000087d60?}, {0x736128?, 0xc000126630?}, {0xc001e2c000, 0x2d82bc, 0x34a000})
	/usr/local/go/src/cmd/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go:387 +0x4a5 fp=0xc020160be8 sp=0xc020160a80 pc=0x619e85
cmd/vendor/golang.org/x/tools/go/types/objectpath.find({0x737a88?, 0xc000087d60?}, {0x736100?, 0xc00009cc60?}, {0xc001e2c000, 0x2d82b9, 0x34a000})
	[... output truncated for readability ... ]
@cr7pt0gr4ph7 cr7pt0gr4ph7 changed the title cmd/vet, go/types: Stack overflow crash when using anonymous types in constraints cmd/vet, go/types: go vet crash when using anonymous types in constraints Mar 16, 2022
@cr7pt0gr4ph7 cr7pt0gr4ph7 changed the title cmd/vet, go/types: go vet crash when using anonymous types in constraints cmd/vet, go/types: go vet crash when using self-recursive anonymous types in constraints Mar 16, 2022
@findleyr findleyr added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Mar 16, 2022
@findleyr
Copy link
Contributor

CC @griesemer @timothy-king

@findleyr
Copy link
Contributor

Thank you for the report. Investigating now.

@findleyr findleyr self-assigned this Mar 16, 2022
@findleyr
Copy link
Contributor

This is a bug in the x/tools/go/types/objectpath package: it needs to cycle-break on type-parameters when searching for objects.

@findleyr findleyr added this to the Go1.19 milestone Mar 16, 2022
@findleyr findleyr added the Soon This needs to be done soon. (regressions, serious bugs, outages) label Mar 16, 2022
@gopherbot
Copy link

Change https://go.dev/cl/393376 mentions this issue: go/types/objectpath: break cycles through type parameters in find

@findleyr
Copy link
Contributor

@gopherbot please backport this to 1.18, it is an infinite recursion when running cmd/vet on valid code.

@gopherbot
Copy link

Backport issue(s) opened: #51727 (for 1.18).

Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://go.dev/wiki/MinorReleases.

gopherbot pushed a commit to golang/tools that referenced this issue Mar 16, 2022
When searching for objects, we naively traversed through type parameter
constraints. This leads to infinite recursion when there are cycles
through type parameter constraints.

Break these cycles by tracking type parameter names that have previously
been encountered. This ensures we walk type parameter constraints at
most once. Note that if the desired object was not found on the first
search of the constraint, there is no need to search again.

For golang/go#51717

Change-Id: Ifcdf4b138a0e95441e485bbb9ee21c01b04eaed4
Reviewed-on: https://go-review.googlesource.com/c/tools/+/393376
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
@gopherbot
Copy link

Change https://go.dev/cl/393373 mentions this issue: all: update vendored golang.org/x/tools

@gopherbot
Copy link

Change https://go.dev/cl/393635 mentions this issue: go/types/objectpath: break cycles through type parameters in find

@dmitshur dmitshur added NeedsFix The path to resolution is known, but the work has not been done. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Mar 17, 2022
@golang golang locked and limited conversation to collaborators Jun 22, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done. release-blocker Soon This needs to be done soon. (regressions, serious bugs, outages)
Projects
None yet
Development

No branches or pull requests

4 participants