Skip to content

cmd/compile: "add some generic composite type optimizations" only partially eliminates addrtaken parameter #26407

@heschi

Description

@heschi

In the following code:

package main

type holder struct {
	seq []string
}

func inlineme(h *holder, DELETEME []string) {
	if &DELETEME == &h.seq {
		return
	}
	h.seq = DELETEME
}

//go:noinline
func intermediate(h *holder, seq []string) {
	inlineme(h, seq)
}

func main() {
	var seq []string
	var h holder
	intermediate(&h, seq)
}

inlineme is unusual in that it takes the address of a parameter, but that parameter doesn't actually escape. When inlineme is inlined, DELETEME is almost entirely eliminated from the resulting code, but its address is still taken and it still exists in the function. I haven't followed step by step, but when the stack maps are eventually generated, they still mark DELETEME as live, even though it's never zeroed. If you happen to grow the stack while inlineme is on it, it reads stack garbage and throws.

This bisects down to CL 106495 (commit f31a18d). I imagine the problem will be something like the address operation causing the variable to be kept in func.Dcl, and then the liveness analysis keeps it live forever because it's a parameter. Or something like that.

This was reduced from a test that calls https://github.com/pmezard/go-difflib/blob/792786c7400a136282c1664665ae0a8db921c6c2/difflib/difflib.go#L115, if it matters, but you need a fairly large test with a fairly large stack to reproduce it so I just eyeballed the SSA dump. Not sure how to turn it into a clean test case.

cc @randall77, @TocarIP, @mundaym

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions