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: avoidable construction of stack objects #43753

mdempsky opened this issue Jan 17, 2021 · 2 comments

cmd/compile: avoidable construction of stack objects #43753

mdempsky opened this issue Jan 17, 2021 · 2 comments


Copy link

@mdempsky mdempsky commented Jan 17, 2021

Compiling the program below with -live shows that x gets turned into a stack object:

package p

var m map[int16]bool

func f() {
        var x struct { p *int; i int16 }
        x.i = g()
        m[x.i] = true

func g() int16
func h()
func j(int16)

This is because the assignment m[x.i] = true passes x.i by reference, causing x to get marked as addrtaken.

Note that the logically equivalent program that replaces m[x.i] = true with tmp := x.i; m[tmp] = true does not create a stack object for x.

@mdempsky mdempsky added this to the Go1.17 milestone Jan 17, 2021
@mdempsky mdempsky self-assigned this Jan 17, 2021
Copy link
Member Author

@mdempsky mdempsky commented Jan 17, 2021

Slightly more realistic test case. x here should not require a stack object either:

package p

var m map[interface{}]bool

func f() {
	x := g()
	m[x] = true

func g() interface{}
func h()

(Edit: Actually, it's an autotmp copy of x that gets the stack object, not x itself. But my larger point is that f shouldn't need stack objects at all, since we statically know the lifetime of all variables there.)

Copy link

@gopherbot gopherbot commented Jan 18, 2021

Change mentions this issue: [dev.regabi] cmd/compile: convert OPANIC argument to interface{} during typecheck

gopherbot pushed a commit that referenced this issue Jan 18, 2021
…ng typecheck

Currently, typecheck leaves arguments to OPANIC as their original
type. This CL changes it to insert implicit OCONVIFACE operations to
convert arguments to `interface{}` like how any other function call
would be handled.

No immediate benefits, other than getting to remove a tiny bit of
special-case logic in order.go's handling of OPANICs. Instead, the
generic code path for handling OCONVIFACE is used, if necessary.
Longer term, this should be marginally helpful for #43753, as it
reduces the number of cases where we need values to be addressable for
runtime calls.

However, this does require adding some hacks to appease existing

1. We need yet another kludge in inline budgeting, to ensure that
reflect.flag.mustBe stays inlinable for cmd/compile/internal/test's

2. Since the OCONVIFACE expressions are now being introduced during
typecheck, they're now visible to escape analysis. So expressions like
"panic(1)" are now seen as "panic(interface{}(1))", and escape
analysis warns that the "interface{}(1)" escapes to the heap. These
have always escaped to heap, just now we're accurately reporting about

(Also, unfortunately fmt.go hides implicit conversions by default in
diagnostics messages, so instead of reporting "interface{}(1) escapes
to heap", it actually reports "1 escapes to heap", which is
confusing. However, this confusing messaging also isn't new.)

Change-Id: Icedf60e1d2e464e219441b8d1233a313770272af
Run-TryBot: Matthew Dempsky <>
TryBot-Result: Go Bot <>
Reviewed-by: Cuong Manh Le <>
Trust: Matthew Dempsky <>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants