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: internal compiler error: invalid memory address or nil pointer dereference #51232

Closed
virtuald opened this issue Feb 17, 2022 · 14 comments
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@virtuald
Copy link

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

$ go version
go version devel go1.18-eaf0405 Wed Feb 16 21:34:51 2022 +0000 darwin/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

N/A

What did you do?

https://go.dev/play/p/V4-OtYakAMj?v=gotip

What did you expect to see?

Some error. Was trying to make a testcase for an inference bug.

What did you see instead?

./prog.go:23:11: internal compiler error: panic: runtime error: invalid memory address or nil pointer dereference

@virtuald
Copy link
Author

https://go.dev/play/p/m_EXRkYORl-?v=gotip is similar, but I think it's slightly simpler, but also weirder?

At a glance, this second version seems mildly similar to #51219, maybe the fix for it at https://go.dev/cl/386335 applies here (cc @danscales)? It's a bit late though, so I haven't looked into how I could try out that CL directly.

@ALTree ALTree added this to the Go1.18 milestone Feb 17, 2022
@ALTree ALTree added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Feb 17, 2022
@ALTree ALTree changed the title cmd/compiler: internal compiler error cmd/compiler: internal compiler error: invalid memory address or nil pointer dereference Feb 17, 2022
@Karitham
Copy link

Karitham commented Feb 17, 2022

I made a simpler one, which applies to my code in #51219 too, I'm pretty sure it's related so putting it there

https://go.dev/play/p/SI6WD_aSX8I?v=gotip

This probably shouldn't compile, but the compiler shouldn't panic

(Also tried with the CL, I'm not so sure it's the same issue)

Edit: Made another issue, unsure it's actually related to this one, #51236

@seankhliao seankhliao changed the title cmd/compiler: internal compiler error: invalid memory address or nil pointer dereference cmd/compile: internal compiler error: invalid memory address or nil pointer dereference Feb 17, 2022
@danscales
Copy link
Contributor

#51219 is related to importing a highly recursive type, so the two failures in this issue are completely separate from that. The two cases appear to be distinct.

@danscales
Copy link
Contributor

I made a simpler one, which applies to my code in #51219 too, I'm pretty sure it's related so putting it there

https://go.dev/play/p/SI6WD_aSX8I?v=gotip

This probably shouldn't compile, but the compiler shouldn't panic

(Also tried with the CL, I'm not so sure it's the same issue)

Edit: Made another issue, unsure it's actually related to this one, #51236

This example is a separate issue from the main one here, and it looks like it is the same as #51236 . So, let's make #51236 the main issue for handling this case (where the error message is something like: "internal compiler error: found illegal assignment main.Foo.UnmarshalJSON.T -> SLICE-[]byte;"

@dr2chase
Copy link
Contributor

So I am looking at this, and where I have gotten thus far is that things go bad like so. I do not know why they go bad, only that the result type for the function-typed c.makeFn is nil.

package main

type RC[RG any] interface {
	~[]RG
}

type Fn[RCT RC[RG], RG any] func(RCT)

type F[RCT RC[RG], RG any] interface {
	Fn() Fn[RCT]
}

type concreteF[RCT RC[RG], RG any] struct {
	makeFn func() Fn[RCT]
}

func (c *concreteF[RCT, RG]) Fn() Fn[RCT] { // (2) tries to markInlBody this method of the type in (1)
	return c.makeFn() // (3) is c.makeFn's type fully instantiated?
	// (type is "func() Fn[RCT]" )
	// (4) In the compiler the result type is a struct, one field per result.
        //     There should be one field (a *types.Field), and it should have type Fn[RCT].
        //     however the *types.Field has a nil type; its non-zero/nil attributes are:
	//        flags types.bitset8 = 2
	//        Pos src.XPos = {index: 2, lico: 57600} 
	//        Offset int64 = -1000000000 
}

func NewConcrete[RCT RC[RG], RG any](Rc RCT) F[RCT] {
	return &concreteF[RCT]{ // (1) tries to markInlBody this type
		makeFn: nil,
	}
}

func main() {}

@mpx

This comment was marked as duplicate.

@danscales
Copy link
Contributor

@mpx I moved your case to a new issue - it is distinct. Thanks for providing it!

@danscales
Copy link
Contributor

@griesemer @findleyr The original test case in this issue (see top issue description, https://go.dev/play/p/V4-OtYakAMj?v=gotip) seems to be a types2 bug (fairly unusual case).

It seems like it is probably happening because the type inference that is needed at line 14 is somewhat happening (so there is no typechecker error), but not completely happening, so types2 is returning a nil type to the compiler.

What's happening is that when we are noding the c.makeFn() call at line 18, the type of that call node is being returned as invalid. Here's some output from dlv from line 31 of cmd/compile/internal/noder/expr.go:

(dlv) p expr
cmd/compile/internal/syntax.Expr(*cmd/compile/internal/syntax.CallExpr) *{
        Fun: cmd/compile/internal/syntax.Expr(*cmd/compile/internal/syntax.SelectorExpr) *{
                X: cmd/compile/internal/syntax.Expr(*cmd/compile/internal/syntax.Name) ...,
                Sel: *(*"cmd/compile/internal/syntax.Name")(0xc00041e240),
                expr: (*"cmd/compile/internal/syntax.expr")(0xc0003e9368),},
        ArgList: []cmd/compile/internal/syntax.Expr len: 0, cap: 0, nil,
        HasDots: false,
        expr: cmd/compile/internal/syntax.expr {
                node: (*"cmd/compile/internal/syntax.node")(0xc000119a70),},}
(dlv) p expr.Fun
cmd/compile/internal/syntax.Expr(*cmd/compile/internal/syntax.SelectorExpr) *{
        X: cmd/compile/internal/syntax.Expr(*cmd/compile/internal/syntax.Name) *{
                Value: "c",
                expr: (*"cmd/compile/internal/syntax.expr")(0xc00041e230),},
        Sel: *cmd/compile/internal/syntax.Name {
                Value: "makeFn",
                expr: (*"cmd/compile/internal/syntax.expr")(0xc00041e250),},
        expr: cmd/compile/internal/syntax.expr {
                node: (*"cmd/compile/internal/syntax.node")(0xc0003e9368),},}
(dlv) p typ
cmd/compile/internal/types2.Type(*cmd/compile/internal/types2.Basic) *{
        kind: Invalid (0),
        info: 0,
        name: "invalid type",}
(dlv)

This invalid type turns into a nil type, which causes the compiler crash later on.

The entire program compiles and runs (since we get the correct valid type for the call) if we change line 14 from:

type concreteF[RCT RC[RG], RG any] struct {
	makeFn func() Fn[RCT]
}

to

type concreteF[RCT RC[RG], RG any] struct {
	makeFn func() Fn[RCT, RG]
}

(I.e. add in the RG typeparam so type inference doesn't need to figure it out).

@findleyr
Copy link
Contributor

Haven't read the entire issue, but this looks like a dupe of #51233, or rather seems likely to have the same root cause.

@griesemer
Copy link
Contributor

@findleyr This code requires core type unification that we recently enabled, otherwise it won't type-check. We may have missed something in that code.

@dr2chase
Copy link
Contributor

I have not read the spec closely, recently, but is a single parameter instantiation of a two-parameter generic supposed to ever work? I.e. concreteF[RCT]{ when the declaration is type concreteF[RCT RC[RG], RG any] ?

@griesemer
Copy link
Contributor

@dr2chase Yes, that is supposed to work, using constraint type inference. There's clearly something wrong here on the type checker side. Actively investigating.

@findleyr
Copy link
Contributor

I have not read the spec closely, recently, but is a single parameter instantiation of a two-parameter generic supposed to ever work? I.e. concreteF[RCT]{ when the declaration is type concreteF[RCT RC[RG], RG any] ?

Yes, we run constraint type inference if not all type parameters are supplied. In this example there is a complex interaction of inference with declaration type checking. We are investigating if this can be fixed.

@gopherbot
Copy link

Change https://go.dev/cl/387918 mentions this issue: types2: delay receiver type validation

@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 3, 2022
@golang golang locked and limited conversation to collaborators Mar 3, 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.
Projects
None yet
Development

No branches or pull requests

10 participants