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: cannot export = (21) node #44325

Closed
rogpeppe opened this issue Feb 17, 2021 · 11 comments
Closed

cmd/compile: cannot export = (21) node #44325

rogpeppe opened this issue Feb 17, 2021 · 11 comments
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@rogpeppe
Copy link
Contributor

rogpeppe commented Feb 17, 2021

commit 2f0da6d

The following testscript example gives gives me an internal compiler error:

cd p1
go install

-- go.mod --
module example

go 1.15
-- go.sum --
-- p1/f.go --
package p1

import (
	"example/p2"
)

func F() {
	p2.FM()
}
-- p2/w.go --
package p2

func FM() func() {
	return func() {
		_ = func() int {
			return 0
		}
	}
}

The error I see is:

> cd p1
$WORK/p1
> go install
[stderr]
# example/p1
./f.go:8:7: internal compiler error: cannot export = (21) node
	==> please file an issue and assign to gri@

goroutine 1 [running]:
runtime/debug.Stack(0xe9d640, 0xc00000e018, 0x0)
	/home/rogpeppe/go/src/runtime/debug/stack.go:24 +0x9f
cmd/compile/internal/base.FatalfAt(0x505000000004, 0xd85733, 0x47, 0xc0006130c8, 0x2, 0x2)
	/home/rogpeppe/go/src/cmd/compile/internal/base/print.go:227 +0x1bc
cmd/compile/internal/base.Fatalf(...)
	/home/rogpeppe/go/src/cmd/compile/internal/base/print.go:196
cmd/compile/internal/typecheck.(*exportWriter).expr(0xc0006c6540, 0xeab610, 0xc0006380a0)
	/home/rogpeppe/go/src/cmd/compile/internal/typecheck/iexport.go:1581 +0x65a
cmd/compile/internal/typecheck.(*exportWriter).exprList(0xc0006c6540, 0xc0006300b0, 0x1, 0x1)
	/home/rogpeppe/go/src/cmd/compile/internal/typecheck/iexport.go:1287 +0x6c
cmd/compile/internal/typecheck.(*exportWriter).stmt(0xc0006c6540, 0xead230, 0xc0003b85f0)
	/home/rogpeppe/go/src/cmd/compile/internal/typetestscript: exit 1
check/iexport.go:1186 +0xadc
cmd/compile/internal/typecheck.(*exportWriter).node(0xc0006c6540, 0xead230, 0xc0003b85f0)
	/home/rogpeppe/go/src/cmd/compile/internal/typecheck/iexport.go:1116 +0x78
cmd/compile/internal/typecheck.(*exportWriter).stmtList(0xc0006c6540, 0xc000630080, 0x1, 0x1)
	/home/rogpeppe/go/src/cmd/compile/internal/typecheck/iexport.go:1109 +0x6c
cmd/compile/internal/typecheck.(*exportWriter).expr(0xc0006c6540, 0xeabc50, 0xc0003b8640)
	/home/rogpeppe/go/src/cmd/compile/internal/typecheck/iexport.go:1395 +0x3ca
cmd/compile/internal/typecheck.(*exportWriter).stmt(0xc0006c6540, 0xeab610, 0xc0003b8690)
	/home/rogpeppe/go/src/cmd/compile/internal/typecheck/iexport.go:1162 +0x44e
cmd/compile/internal/typecheck.(*exportWriter).node(0xc0006c6540, 0xeab610, 0xc0003b8690)
	/home/rogpeppe/go/src/cmd/compile/internal/typecheck/iexport.go:1116 +0x78
cmd/compile/internal/typecheck.(*exportWriter).stmtList(0xc0006c6540, 0xc000050870, 0x1, 0x1)
	/home/rogpeppe/go/src/cmd/compile/internal/typecheck/iexport.go:1109 +0x6c
cmd/compile/internal/typecheck.(*exportWriter).expr(0xc0006c6540, 0xeabc50, 0xc0003b86e0)
	/home/rogpeppe/go/src/cmd/compile/internal/typecheck/iexport.go:1395 +0x3ca
cmd/compile/internal/typecheck.(*exportWriter).exprList(0xc0006c6540, 0xc000050880, 0x1, 0x1)
	/home/rogpeppe/go/src/cmd/compile/internal/typecheck/iexport.go:1287 +0x6c
cmd/compile/internal/typecheck.(*exportWriter).stmt(0xc0006c6540, 0xead230, 0xc0003b8730)
	/home/rogpeppe/go/src/cmd/compile/internal/typecheck/iexport.go:1186 +0xadc
cmd/compile/internal/typecheck.(*exportWriter).node(0xc0006c6540, 0xead230, 0xc0003b8730)
	/home/rogpeppe/go/src/cmd/compile/internal/typecheck/iexport.go:1116 +0x78
cmd/compile/internal/typecheck.(*exportWriter).stmtList(0xc0006c6540, 0xc000050890, 0x1, 0x1)
	/home/rogpeppe/go/src/cmd/compile/internal/typecheck/iexport.go:1109 +0x6c
cmd/compile/internal/typecheck.(*exportWriter).funcBody(0xc0006c6540, 0xc00013a420)
	/home/rogpeppe/go/src/cmd/compile/internal/typecheck/iexport.go:1104 +0x8b
cmd/compile/internal/typecheck.(*iexporter).doInline(0xc0001080a0, 0xc0003aea90)
	/home/rogpeppe/go/src/cmd/compile/internal/typecheck/iexport.go:545 +0xd3
cmd/compile/internal/typecheck.(*exportWriter).funcExt(0xc0006c6460, 0xc0003aea90)
	/home/rogpeppe/go/src/cmd/compile/internal/typecheck/iexport.go:1042 +0x1cf
cmd/compile/internal/typecheck.(*iexporter).doDecl(0xc0001080a0, 0xc0003aea90)
	/home/rogpeppe/go/src/cmd/compile/internal/typecheck/iexport.go:458 +0x147
cmd/compile/internal/typecheck.WriteExports(0xc0006ac480)
	/home/rogpeppe/go/src/cmd/compile/internal/typecheck/iexport.go:274 +0x2ab
cmd/compile/internal/gc.dumpexport(0xc0006ba240)
	/home/rogpeppe/go/src/cmd/compile/internal/gc/export.go:34 +0x1a5
cmd/compile/internal/gc.dumpCompilerObj(0xc0006ba240)
	/home/rogpeppe/go/src/cmd/compile/internal/gc/obj.go:106 +0x39
cmd/compile/internal/gc.dumpobj1(0x7ffc3ab34911, 0x4e, 0x3)
	/home/rogpeppe/go/src/cmd/compile/internal/gc/obj.go:62 +0x174
cmd/compile/internal/gc.dumpobj()
	/home/rogpeppe/go/src/cmd/compile/internal/gc/obj.go:43 +0x50
cmd/compile/internal/gc.Main(0xd8bf40)
	/home/rogpeppe/go/src/cmd/compile/internal/gc/main.go:299 +0xefa
main.main()
	/home/rogpeppe/go/src/cmd/compile/main.go:54 +0xb1


[exit status 2]
FAIL: /tmp/testscript564923438/0/script.txt:2: unexpected go command failure
error running /tmp/export-bug.txt in /tmp/testscript564923438/0
@mvdan mvdan added the NeedsFix The path to resolution is known, but the work has not been done. label Feb 17, 2021
@mvdan mvdan added this to the Go1.17 milestone Feb 17, 2021
@rogpeppe
Copy link
Contributor Author

rogpeppe commented Feb 17, 2021

Here's a related example that produces a different compiler error:

cd p1
go install

-- go.mod --
module example

go 1.15
-- go.sum --
-- p1/f.go --
package metrics

import "example/p2"

func F() {
	p2.FM("")
}
-- p2/w.go --
package p2

type W struct {
	M func(string) string
}

func FM(m string) func(W) {
	return func(pw W) {
		pw.M = func(string) string {
			return m
		}
	}
}

From the above code I get this error:

> cd p1
$WORK/p1
> go install
[stderr]
# example/p1
./f.go:6:7: internal compiler error: 'F.func2': Value live at entry. It shouldn't be. func F.func2, node p2.m, value nil

goroutine 66 [running]:
runtime/debug.Stack(0xe9d640, 0xc00000e018, 0x0)
	/home/rogpeppe/go/src/runtime/debug/stack.go:24 +0x9f
cmd/compile/internal/base.FatalfAt(0x90a000000004, 0xc0007b0000, 0x46, 0xc000782300, 0x4, 0x4)
	/home/rogpeppe/go/src/cmd/compile/internal/base/print.go:227 +0x1bc
cmd/compile/internal/base.Fatalf(...)
	/home/rogpeppe/go/src/cmd/compile/internal/base/print.go:196
cmd/compile/internal/ssagen.(*ssafn).Fatalf(0xc000780150, 0x90a000000004, 0xd84d8e, 0x40, 0xc000780300, 0x3, 0x3)
	/home/rogpeppe/go/src/cmd/compile/internal/ssagen/ssa.go:7210 +0x1a7
cmd/compile/internal/ssagen.(*state).Fatalf(...)
	/home/rogpeppe/go/src/cmd/compile/internal/ssagen/ssa.go:845
cmd/compile/internal/ssagen.(*state).variable(0xc0007a6000, 0xeacd80, 0xc0003ad6c0, 0xc00005eea0, 0xc00008ee40)
	/home/rogpeppe/go/src/cmd/compile/internal/ssagentestscript: exit 1
/ssa.go:6213 +0x3b5
cmd/compile/internal/ssagen.(*state).expr(0xc0007a6000, 0xeacd80, 0xc0003ad6c0, 0x0)
	/home/rogpeppe/go/src/cmd/compile/internal/ssagen/ssa.go:2297 +0x3b1f
cmd/compile/internal/ssagen.(*state).stmt(0xc0007a6000, 0xeab610, 0xc000790550)
	/home/rogpeppe/go/src/cmd/compile/internal/ssagen/ssa.go:1498 +0x2ae
cmd/compile/internal/ssagen.(*state).stmtList(0xc0007a6000, 0xc000784120, 0x1, 0x1)
	/home/rogpeppe/go/src/cmd/compile/internal/ssagen/ssa.go:1269 +0x68
cmd/compile/internal/ssagen.(*state).stmt(0xc0007a6000, 0xeab868, 0xc000782240)
	/home/rogpeppe/go/src/cmd/compile/internal/ssagen/ssa.go:1292 +0x1689
cmd/compile/internal/ssagen.(*state).stmtList(0xc0007a6000, 0xc0007821c0, 0x4, 0x4)
	/home/rogpeppe/go/src/cmd/compile/internal/ssagen/ssa.go:1269 +0x68
cmd/compile/internal/ssagen.(*state).stmt(0xc0007a6000, 0xeab610, 0xc0003b6c80)
	/home/rogpeppe/go/src/cmd/compile/internal/ssagen/ssa.go:1287 +0xed
cmd/compile/internal/ssagen.(*state).stmtList(0xc0007a6000, 0xc000784090, 0x1, 0x1)
	/home/rogpeppe/go/src/cmd/compile/internal/ssagen/ssa.go:1269 +0x68
cmd/compile/internal/ssagen.buildssa(0xc00013a840, 0x0, 0x0)
	/home/rogpeppe/go/src/cmd/compile/internal/ssagen/ssa.go:522 +0x1145
cmd/compile/internal/ssagen.Compile(0xc00013a840, 0x0)
	/home/rogpeppe/go/src/cmd/compile/internal/ssagen/pgen.go:168 +0x5d
cmd/compile/internal/gc.compileFunctions.func2.1(0xc00079a000, 0xc00013a840, 0xc00078a050, 0xc00078c060)
	/home/rogpeppe/go/src/cmd/compile/internal/gc/compile.go:127 +0x65
created by cmd/compile/internal/gc.compileFunctions.func2
	/home/rogpeppe/go/src/cmd/compile/internal/gc/compile.go:125 +0x8e


[exit status 2]
FAIL: /tmp/testscript633248317/0/script.txt:2: unexpected go command failure
error running /tmp/export-bug.txt in /tmp/testscript633248317/0

@mdempsky
Copy link
Member

/cc @danscales

This seems related to exporting closures.

@danscales danscales assigned danscales and unassigned griesemer Feb 17, 2021
@danscales
Copy link
Contributor

Yes, thanks, I will take a look.

@tonyghita
Copy link

tonyghita commented Feb 17, 2021

I have a similar issue but no simple reproducer available. I was able to git bisect the issue to commit f2c0c2b.

my/pkg/pkg_test.go:133:22: internal compiler error: 'TestX.func5': Value live at entry. It shouldn't be. func TestX.func5, node ~R0, value v54

goroutine 5 [running]:
runtime/debug.Stack(0x19ad760, 0xc00012c008, 0x0)
	/Users/tonyghita/src/goroot/src/runtime/debug/stack.go:24 +0x9f
cmd/compile/internal/gc.Fatalf(0xc02579c960, 0x46, 0xc01dc60640, 0x4, 0x4)
	/Users/tonyghita/src/goroot/src/cmd/compile/internal/gc/subr.go:199 +0x1b0
cmd/compile/internal/gc.(*ssafn).Fatalf(0xc01dc35500, 0x8516000000072, 0x18b213f, 0x40, 0xc01dc357d0, 0x3, 0x3)
	/Users/tonyghita/src/goroot/src/cmd/compile/internal/gc/ssa.go:7060 +0x1a5
cmd/compile/internal/gc.(*state).Fatalf(...)
	/Users/tonyghita/src/goroot/src/cmd/compile/internal/gc/ssa.go:688
cmd/compile/internal/gc.(*simplePhiState).insertPhis(0xc00560fb48)
	/Users/tonyghita/src/goroot/src/cmd/compile/internal/gc/phi.go:469 +0x871
cmd/compile/internal/gc.(*state).insertPhis(0xc01da6bd40)
	/Users/tonyghita/src/goroot/src/cmd/compile/internal/gc/phi.go:35 +0x1aa
cmd/compile/internal/gc.buildssa(0xc003421760, 0x0, 0x0)
	/Users/tonyghita/src/goroot/src/cmd/compile/internal/gc/ssa.go:466 +0x11a5
cmd/compile/internal/gc.compileSSA(0xc003421760, 0x0)
	/Users/tonyghita/src/goroot/src/cmd/compile/internal/gc/pgen.go:319 +0x5d
cmd/compile/internal/gc.compileFunctions.func2(0xc00a6a9020, 0xc005bb4040, 0x0)
	/Users/tonyghita/src/goroot/src/cmd/compile/internal/gc/pgen.go:384 +0x4d
created by cmd/compile/internal/gc.compileFunctions
	/Users/tonyghita/src/goroot/src/cmd/compile/internal/gc/pgen.go:382 +0x129

@mdempsky
Copy link
Member

@tonyghita That commit is included in Go 1.16. I think that's separate from this issue or #44335, which are about failures that appeared post 1.16.

It would be great if you would file a new issue and provide steps to reproduce it. Thanks.

@tonyghita
Copy link

@mdempsky I've created #44355. Apologies for the mixup on this issue

@mdempsky
Copy link
Member

From the stack trace, it looks like the issue is that iexport is finding an OAS node inside of the results of the innermost function literal's return statement. That suggests it's exporting the function body that was rewritten by walk, rather than the function body that cloned during inlining.

@cuonglm
Copy link
Member

cuonglm commented Feb 18, 2021

From the stack trace, it looks like the issue is that iexport is finding an OAS node inside of the results of the innermost function literal's return statement. That suggests it's exporting the function body that was rewritten by walk, rather than the function body that cloned during inlining.

This is right, e.g, if we change FM to:

func FM() func() {
	return func() {
		_ = func() (i int) {
			return
		}
	}
}

or:

func FM() func() {
	return func() {
		_ = func() { _ = nil }
	}
}

Then it compiles ok.

@gopherbot
Copy link

Change https://golang.org/cl/293669 mentions this issue: cmd/compile: fix import/export ORETURN

@danscales
Copy link
Contributor

There are two different bugs here, and I have a fix for both, I believe. The export = (21) bug is because the check to avoid creating a new closure function in tcClosure is not quite right. Unfortunately, tcClosure has the side effect of creating a new closure function, but we don't want to do that when we are type-checking a function inline body. @cuonglm I would say your change is dealing with symptoms, but not with the problem.

The second bug (rogpeppe's second example) relates to how we are importing/exporting closure vars when they are referencing variables across multiple closures. I will re-open #44335 as a representative of that bug (Value live at entry)

@gopherbot
Copy link

Change https://golang.org/cl/294211 mentions this issue: cmd/compile: fix check to avoid creating new closure function when typechecking inline body

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

8 participants