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
NeedsFix
Milestone

Comments

@virtuald
Copy link

@virtuald virtuald commented Feb 17, 2022

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

@virtuald virtuald commented Feb 17, 2022

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 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 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

@danscales danscales commented Feb 17, 2022

#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

@danscales danscales 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

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

@dr2chase dr2chase commented Feb 17, 2022

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

@danscales danscales commented Feb 24, 2022

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

@danscales
Copy link
Contributor

@danscales danscales commented Feb 24, 2022

@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

@findleyr findleyr commented Feb 24, 2022

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

@griesemer griesemer commented Feb 24, 2022

@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

@dr2chase dr2chase commented Feb 24, 2022

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

@griesemer griesemer commented Feb 24, 2022

@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

@findleyr findleyr commented Feb 24, 2022

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

@gopherbot gopherbot commented Feb 24, 2022

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

@dmitshur dmitshur added NeedsFix and removed NeedsInvestigation labels Mar 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsFix
Projects
None yet
Development

No branches or pull requests

10 participants