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/compile: tricky map key causes internal compiler error #14988

Closed
mdempsky opened this issue Mar 27, 2016 · 5 comments
Closed

cmd/compile: tricky map key causes internal compiler error #14988

mdempsky opened this issue Mar 27, 2016 · 5 comments
Milestone

Comments

@mdempsky
Copy link
Member

package p

type v []m
type m map[x]int
type x [4]v

Yields:

/tmp/p.go:6: internal compiler error: slice can't be a map key: v

The code is invalid anyway, but we should be detecting that during type checking. It shouldn't be triggering an ICE.

@dgryski
Copy link
Contributor

dgryski commented Mar 29, 2016

Sounds like we should run the new SSA backend against https://github.com/dvyukov/gosmith / go-fuzz.

@randall77
Copy link
Contributor

This error isn't from the SSA backend. It has existed since 1.5.
Go 1.4 happily accepts this code. Probably worse than an ICE.

@bradfitz bradfitz added this to the Go1.7 milestone Apr 9, 2016
@tshprecher
Copy link
Contributor

I did a little bit of investigating. Consider the following two programs:

P_1:

package p

type k [1]m
type m map[k]int

OUT_1:
./p_1.go:4: invalid map key type k

The first line creates a forward declaration for k. The next line sets the value of m to a map with key 'k' and runs checkMapKeyType. It fails properly because [1]map[anything]anything is not a comparison type.

Now consider the same program with the two lines swapped:

P_2:

package p

type m map[k]int
type k [1]m

OUT_2:
./p_2.go:4: internal compiler error: bad type for map key: m

The difference is subtle. The first line creates a forward type for m. The second line creates a forward type for k, and checkMapKeyType([1]m) is called. The entire key [1]m is treated as a forward type instead of as array with an element that's a forward type. Instead of erroring out, checkMapKeyType does nothing and waits for the type [1]m to be fully resolved, which I don't believe will ever happen because of the mutually recursive type definitions. This is eventually caught here:

https://github.com/golang/go/blob/master/src/cmd/compile/internal/gc/reflect.go#L1006

@tshprecher
Copy link
Contributor

I took at stab at a fix: https://go-review.googlesource.com/#/c/21830/

New results:

P_1 (original bug):

package p

type v []m
type m map[x]int
type x [4]v

OUT_1:
./orig.go:4: invalid map key type x

P_2:

package p

type m map[k]int
type k [1]m

OUT_2:

./p_2.go:3: invalid map key type k

@gopherbot
Copy link

CL https://golang.org/cl/21830 mentions this issue.

@golang golang locked and limited conversation to collaborators Apr 13, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants