// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gc

import (
	"cmd/compile/internal/types"
	"fmt"
	"strconv"
	"strings"
)

// Escape analysis.

// An escape analysis pass for a set of functions. The
// analysis assumes that closures and the functions in which
// they appear are analyzed together, so that the aliasing
// between their variables can be modeled more precisely.
//
// First escfunc, esc and escassign recurse over the ast of
// each function to dig out flow(dst,src) edges between any
// pointer-containing  nodes and store those edges in
// e.nodeEscState(dst).Flowsrc. For values assigned to a
// variable in an outer scope or used as a return value,
// they store a flow(theSink, src) edge to a fake node 'the
// Sink'.  For variables referenced in closures, an edge
// flow(closure, &var) is recorded and the flow of a closure
// itself to an outer scope is tracked the same way as other
// variables.
//
// Then escflood walks the graph in destination-to-source
// order, starting at theSink, propagating a computed
// "escape level", and tags as escaping values it can
// reach that are either & (address-taken) nodes or new(T),
// and tags pointer-typed or pointer-containing function
// parameters it can reach as leaking.
//
// If a value's address is taken but the address does not escape,
// then the value can stay on the stack. If the value new(T) does
// not escape, then new(T) can be rewritten into a stack allocation.
// The same is true of slice literals.

// If newescape is true, then escape.go drives escape analysis instead
// of esc.go.
var newescape bool

func escapes(all []*Node) {
	esc := escAnalyze
	if newescape {
		esc = escapeFuncs
	}
	visitBottomUp(all, esc)
}

const (
	EscFuncUnknown = 0 + iota
	EscFuncPlanned
	EscFuncStarted
	EscFuncTagged
)

// A Level encodes the reference state and context applied to
// (stack, heap) allocated memory.
//
// value is the overall sum of *(1) and &(-1) operations encountered
// along a path from a destination (sink, return value) to a source
// (allocation, parameter).
//
// suffixValue is the maximum-copy-started-suffix-level on
// a flow path from a sink/destination.  That is, a value
// with suffixValue N is guaranteed to be dereferenced at least
// N deep (chained applications of DOTPTR or IND or INDEX)
// before the result is assigned to a sink.
//
// For example, suppose x is a pointer to T, declared type T struct { left, right *T }
//   sink = x.left.left --> level(x)=2, x is reached via two dereferences (DOTPTR) and does not escape to sink.
//   sink = &T{right:x} --> level(x)=-1, x is accessible from sink via one "address of"
//   sink = &T{right:&T{right:x}} --> level(x)=-2, x is accessible from sink via two "address of"
//
// However, in the next example x's level value and suffixValue differ:
//   sink = &T{right:&T{right:x.left}} --> level(x).value=-1, level(x).suffixValue=1
// The positive suffixValue indicates that x is NOT accessible
// from sink. Without a separate suffixValue to capture this, x would
// appear to escape because its "value" would be -1.  (The copy
// operations are sometimes implicit in the source code; in this case,
// the value of x.left was copied into a field of an newly allocated T).
//
// Each node's level (value and suffixValue) is the maximum for
// all flow paths from (any) sink to that node.

// There's one of these for each Node, and the integer values
// rarely exceed even what can be stored in 4 bits, never mind 8.
type Level struct {
	value, suffixValue int8
}

// There are loops in the escape graph,
// causing arbitrary recursion into deeper and deeper
// levels. Cut this off safely by making minLevel sticky:
// once you get that deep, you cannot go down any further
// but you also cannot go up any further. This is a
// conservative fix. Making minLevel smaller (more negative)
// would handle more complex chains of indirections followed
// by address-of operations, at the cost of repeating the
// traversal once for each additional allowed level when a
// loop is encountered. Using -2 suffices to pass all the
// tests we have written so far, which we assume matches the
// level of complexity we want the escape analysis code to
// handle.
const MinLevel = -2

func (l Level) int() int {
	return int(l.value)
}

func levelFrom(i int) Level {
	if i <= MinLevel {
		return Level{value: MinLevel}
	}
	return Level{value: int8(i)}
}

func satInc8(x int8) int8 {
	if x == 127 {
		return 127
	}
	return x + 1
}

func min8(a, b int8) int8 {
	if a < b {
		return a
	}
	return b
}

func max8(a, b int8) int8 {
	if a > b {
		return a
	}
	return b
}

// inc returns the level l + 1, representing the effect of an indirect (*) operation.
func (l Level) inc() Level {
	if l.value <= MinLevel {
		return Level{value: MinLevel}
	}
	return Level{value: satInc8(l.value), suffixValue: satInc8(l.suffixValue)}
}

// dec returns the level l - 1, representing the effect of an address-of (&) operation.
func (l Level) dec() Level {
	if l.value <= MinLevel {
		return Level{value: MinLevel}
	}
	return Level{value: l.value - 1, suffixValue: l.suffixValue - 1}
}

// copy returns the level for a copy of a value with level l.
// The resulting suffixValue is at least zero, or larger if it was already larger.
func (l Level) copy() Level {
	return Level{value: l.value, suffixValue: max8(l.suffixValue, 0)}
}

func (l1 Level) min(l2 Level) Level {
	return Level{
		value:       min8(l1.value, l2.value),
		suffixValue: min8(l1.suffixValue, l2.suffixValue)}
}

// guaranteedDereference returns the number of dereferences
// applied to a pointer before addresses are taken/generated.
// This is the maximum level computed from path suffixes starting
// with copies where paths flow from destination to source.
func (l Level) guaranteedDereference() int {
	return int(l.suffixValue)
}

// An EscStep documents one step in the path from memory
// that is heap allocated to the (alleged) reason for the
// heap allocation.
type EscStep struct {
	src, dst *Node    // the endpoints of this edge in the escape-to-heap chain.
	where    *Node    // sometimes the endpoints don't match source locations; set 'where' to make that right
	parent   *EscStep // used in flood to record path
	why      string   // explanation for this step in the escape-to-heap chain
	busy     bool     // used in prevent to snip cycles.
}

type NodeEscState struct {
	Curfn             *Node
	Flowsrc           []EscStep // flow(this, src)
	Retval            Nodes     // on OCALLxxx, list of dummy return values
	Loopdepth         int32     // -1: global, 0: return variables, 1:function top level, increased inside function for every loop or label to mark scopes
	Level             Level
	Walkgen           uint32
	Maxextraloopdepth int32
}

func (e *EscState) nodeEscState(n *Node) *NodeEscState {
	if nE, ok := n.Opt().(*NodeEscState); ok {
		return nE
	}
	if n.Opt() != nil {
		Fatalf("nodeEscState: opt in use (%T)", n.Opt())
	}
	nE := &NodeEscState{
		Curfn: Curfn,
	}
	n.SetOpt(nE)
	e.opts = append(e.opts, n)
	return nE
}

func (e *EscState) track(n *Node) {
	if Curfn == nil {
		Fatalf("EscState.track: Curfn nil")
	}
	n.Esc = EscNone // until proven otherwise
	nE := e.nodeEscState(n)
	nE.Loopdepth = e.loopdepth
	e.noesc = append(e.noesc, n)
}

// Escape constants are numbered in order of increasing "escapiness"
// to help make inferences be monotonic. With the exception of
// EscNever which is sticky, eX < eY means that eY is more exposed
// than eX, and hence replaces it in a conservative analysis.
const (
	EscUnknown        = iota
	EscNone           // Does not escape to heap, result, or parameters.
	EscReturn         // Is returned or reachable from returned.
	EscHeap           // Reachable from the heap
	EscNever          // By construction will not escape.
	EscBits           = 3
	EscMask           = (1 << EscBits) - 1
	EscContentEscapes = 1 << EscBits // value obtained by indirect of parameter escapes to heap
	EscReturnBits     = EscBits + 1
	// Node.esc encoding = | escapeReturnEncoding:(width-4) | contentEscapes:1 | escEnum:3
)

// escMax returns the maximum of an existing escape value
// (and its additional parameter flow flags) and a new escape type.
func escMax(e, etype uint16) uint16 {
	if e&EscMask >= EscHeap {
		// normalize
		if e&^EscMask != 0 {
			Fatalf("Escape information had unexpected return encoding bits (w/ EscHeap, EscNever), e&EscMask=%v", e&EscMask)
		}
	}
	if e&EscMask > etype {
		return e
	}
	if etype == EscNone || etype == EscReturn {
		return (e &^ EscMask) | etype
	}
	return etype
}

// For each input parameter to a function, the escapeReturnEncoding describes
// how the parameter may leak to the function's outputs. This is currently the
// "level" of the leak where level is 0 or larger (negative level means stored into
// something whose address is returned -- but that implies stored into the heap,
// hence EscHeap, which means that the details are not currently relevant. )
const (
	bitsPerOutputInTag = 3                                 // For each output, the number of bits for a tag
	bitsMaskForTag     = uint16(1<<bitsPerOutputInTag) - 1 // The bit mask to extract a single tag.
	maxEncodedLevel    = int(bitsMaskForTag - 1)           // The largest level that can be stored in a tag.
)

type EscState struct {
	// Fake node that all
	//   - return values and output variables
	//   - parameters on imported functions not marked 'safe'
	//   - assignments to global variables
	// flow to.
	theSink Node

	dsts      []*Node // all dst nodes
	loopdepth int32   // for detecting nested loop scopes
	pdepth    int     // for debug printing in recursions.
	dstcount  int     // diagnostic
	edgecount int     // diagnostic
	noesc     []*Node // list of possible non-escaping nodes, for printing
	recursive bool    // recursive function or group of mutually recursive functions.
	opts      []*Node // nodes with .Opt initialized
	walkgen   uint32
}

func newEscState(recursive bool) *EscState {
	e := new(EscState)
	e.theSink.Op = ONAME
	e.theSink.Orig = &e.theSink
	e.theSink.SetClass(PEXTERN)
	e.theSink.Sym = lookup(".sink")
	e.nodeEscState(&e.theSink).Loopdepth = -1
	e.recursive = recursive
	return e
}

func (e *EscState) stepWalk(dst, src *Node, why string, parent *EscStep) *EscStep {
	// TODO: keep a cache of these, mark entry/exit in escwalk to avoid allocation
	// Or perhaps never mind, since it is disabled unless printing is on.
	// We may want to revisit this, since the EscStep nodes would make
	// an excellent replacement for the poorly-separated graph-build/graph-flood
	// stages.
	if Debug['m'] == 0 {
		return nil
	}
	return &EscStep{src: src, dst: dst, why: why, parent: parent}
}

func (e *EscState) stepAssign(step *EscStep, dst, src *Node, why string) *EscStep {
	if Debug['m'] == 0 {
		return nil
	}
	if step != nil { // Caller may have known better.
		if step.why == "" {
			step.why = why
		}
		if step.dst == nil {
			step.dst = dst
		}
		if step.src == nil {
			step.src = src
		}
		return step
	}
	return &EscStep{src: src, dst: dst, why: why}
}

func (e *EscState) stepAssignWhere(dst, src *Node, why string, where *Node) *EscStep {
	if Debug['m'] == 0 {
		return nil
	}
	return &EscStep{src: src, dst: dst, why: why, where: where}
}

// funcSym returns fn.Func.Nname.Sym if no nils are encountered along the way.
func funcSym(fn *Node) *types.Sym {
	if fn == nil || fn.Func.Nname == nil {
		return nil
	}
	return fn.Func.Nname.Sym
}

// curfnSym returns n.Curfn.Nname.Sym if no nils are encountered along the way.
func (e *EscState) curfnSym(n *Node) *types.Sym {
	nE := e.nodeEscState(n)
	return funcSym(nE.Curfn)
}

func escAnalyze(all []*Node, recursive bool) {
	e := newEscState(recursive)

	for _, n := range all {
		if n.Op == ODCLFUNC {
			n.Esc = EscFuncPlanned
			if Debug['m'] > 3 {
				Dump("escAnalyze", n)
			}

		}
	}

	// flow-analyze functions
	for _, n := range all {
		if n.Op == ODCLFUNC {
			e.escfunc(n)
		}
	}

	// visit the upstream of each dst, mark address nodes with
	// addrescapes, mark parameters unsafe
	escapes := make([]uint16, len(e.dsts))
	for i, n := range e.dsts {
		escapes[i] = n.Esc
	}
	for _, n := range e.dsts {
		e.escflood(n)
	}
	for {
		done := true
		for i, n := range e.dsts {
			if n.Esc != escapes[i] {
				done = false
				if Debug['m'] > 2 {
					Warnl(n.Pos, "Reflooding %v %S", e.curfnSym(n), n)
				}
				escapes[i] = n.Esc
				e.escflood(n)
			}
		}
		if done {
			break
		}
	}

	// for all top level functions, tag the typenodes corresponding to the param nodes
	for _, n := range all {
		if n.Op == ODCLFUNC {
			esctag(n)
		}
	}

	if Debug['m'] != 0 {
		for _, n := range e.noesc {
			if n.Esc == EscNone && n.Op != OADDR {
				Warnl(n.Pos, "%v %S does not escape", e.curfnSym(n), n)
			}
		}
	}

	for _, x := range e.opts {
		x.SetOpt(nil)
	}
}

func (e *EscState) escfunc(fn *Node) {
	if fn.Esc != EscFuncPlanned {
		Fatalf("repeat escfunc %v", fn.Func.Nname)
	}
	fn.Esc = EscFuncStarted

	saveld := e.loopdepth
	e.loopdepth = 1
	savefn := Curfn
	Curfn = fn

	for _, ln := range Curfn.Func.Dcl {
		if ln.Op != ONAME {
			continue
		}
		lnE := e.nodeEscState(ln)
		switch ln.Class() {
		// out params are in a loopdepth between the sink and all local variables
		case PPARAMOUT:
			lnE.Loopdepth = 0

		case PPARAM:
			lnE.Loopdepth = 1
			if ln.Type != nil && !types.Haspointers(ln.Type) {
				break
			}
			if Curfn.Nbody.Len() == 0 && !Curfn.Noescape() {
				ln.Esc = EscHeap
			} else {
				ln.Esc = EscNone // prime for escflood later
			}
			e.noesc = append(e.noesc, ln)
		}
	}

	// in a mutually recursive group we lose track of the return values
	if e.recursive {
		for _, ln := range Curfn.Func.Dcl {
			if ln.Op == ONAME && ln.Class() == PPARAMOUT {
				e.escflows(&e.theSink, ln, e.stepAssign(nil, ln, ln, "returned from recursive function"))
			}
		}
	}

	e.escloopdepthlist(Curfn.Nbody)
	e.esclist(Curfn.Nbody, Curfn)
	Curfn = savefn
	e.loopdepth = saveld
}

// Mark labels that have no backjumps to them as not increasing e.loopdepth.
// Walk hasn't generated (goto|label).Left.Sym.Label yet, so we'll cheat
// and set it to one of the following two. Then in esc we'll clear it again.
var (
	looping    Node
	nonlooping Node
)

func (e *EscState) escloopdepthlist(l Nodes) {
	for _, n := range l.Slice() {
		e.escloopdepth(n)
	}
}

func (e *EscState) escloopdepth(n *Node) {
	if n == nil {
		return
	}

	e.escloopdepthlist(n.Ninit)

	switch n.Op {
	case OLABEL:
		if n.Sym == nil {
			Fatalf("esc:label without label: %+v", n)
		}

		// Walk will complain about this label being already defined, but that's not until
		// after escape analysis. in the future, maybe pull label & goto analysis out of walk and put before esc
		n.Sym.Label = asTypesNode(&nonlooping)

	case OGOTO:
		if n.Sym == nil {
			Fatalf("esc:goto without label: %+v", n)
		}

		// If we come past one that's uninitialized, this must be a (harmless) forward jump
		// but if it's set to nonlooping the label must have preceded this goto.
		if asNode(n.Sym.Label) == &nonlooping {
			n.Sym.Label = asTypesNode(&looping)
		}
	}

	e.escloopdepth(n.Left)
	e.escloopdepth(n.Right)
	e.escloopdepthlist(n.List)
	e.escloopdepthlist(n.Nbody)
	e.escloopdepthlist(n.Rlist)
}

func (e *EscState) esclist(l Nodes, parent *Node) {
	for _, n := range l.Slice() {
		e.esc(n, parent)
	}
}

func isSliceSelfAssign(dst, src *Node) bool {
	// Detect the following special case.
	//
	//	func (b *Buffer) Foo() {
	//		n, m := ...
	//		b.buf = b.buf[n:m]
	//	}
	//
	// This assignment is a no-op for escape analysis,
	// it does not store any new pointers into b that were not already there.
	// However, without this special case b will escape, because we assign to OIND/ODOTPTR.
	// Here we assume that the statement will not contain calls,
	// that is, that order will move any calls to init.
	// Otherwise base ONAME value could change between the moments
	// when we evaluate it for dst and for src.

	// dst is ONAME dereference.
	if dst.Op != ODEREF && dst.Op != ODOTPTR || dst.Left.Op != ONAME {
		return false
	}
	// src is a slice operation.
	switch src.Op {
	case OSLICE, OSLICE3, OSLICESTR:
		// OK.
	case OSLICEARR, OSLICE3ARR:
		// Since arrays are embedded into containing object,
		// slice of non-pointer array will introduce a new pointer into b that was not already there
		// (pointer to b itself). After such assignment, if b contents escape,
		// b escapes as well. If we ignore such OSLICEARR, we will conclude
		// that b does not escape when b contents do.
		//
		// Pointer to an array is OK since it's not stored inside b directly.
		// For slicing an array (not pointer to array), there is an implicit OADDR.
		// We check that to determine non-pointer array slicing.
		if src.Left.Op == OADDR {
			return false
		}
	default:
		return false
	}
	// slice is applied to ONAME dereference.
	if src.Left.Op != ODEREF && src.Left.Op != ODOTPTR || src.Left.Left.Op != ONAME {
		return false
	}
	// dst and src reference the same base ONAME.
	return dst.Left == src.Left.Left
}

// isSelfAssign reports whether assignment from src to dst can
// be ignored by the escape analysis as it's effectively a self-assignment.
func isSelfAssign(dst, src *Node) bool {
	if isSliceSelfAssign(dst, src) {
		return true
	}

	// Detect trivial assignments that assign back to the same object.
	//
	// It covers these cases:
	//	val.x = val.y
	//	val.x[i] = val.y[j]
	//	val.x1.x2 = val.x1.y2
	//	... etc
	//
	// These assignments do not change assigned object lifetime.

	if dst == nil || src == nil || dst.Op != src.Op {
		return false
	}

	switch dst.Op {
	case ODOT, ODOTPTR:
		// Safe trailing accessors that are permitted to differ.
	case OINDEX:
		if mayAffectMemory(dst.Right) || mayAffectMemory(src.Right) {
			return false
		}
	default:
		return false
	}

	// The expression prefix must be both "safe" and identical.
	return samesafeexpr(dst.Left, src.Left)
}

// mayAffectMemory reports whether n evaluation may affect program memory state.
// If expression can't affect it, then it can be safely ignored by the escape analysis.
func mayAffectMemory(n *Node) bool {
	// We may want to use "memory safe" black list instead of general
	// "side-effect free", which can include all calls and other ops
	// that can affect allocate or change global state.
	// It's safer to start from a whitelist for now.
	//
	// We're ignoring things like division by zero, index out of range,
	// and nil pointer dereference here.
	switch n.Op {
	case ONAME, OCLOSUREVAR, OLITERAL:
		return false

	// Left+Right group.
	case OINDEX, OADD, OSUB, OOR, OXOR, OMUL, OLSH, ORSH, OAND, OANDNOT, ODIV, OMOD:
		return mayAffectMemory(n.Left) || mayAffectMemory(n.Right)

	// Left group.
	case ODOT, ODOTPTR, ODEREF, OCONVNOP, OCONV, OLEN, OCAP,
		ONOT, OBITNOT, OPLUS, ONEG, OALIGNOF, OOFFSETOF, OSIZEOF:
		return mayAffectMemory(n.Left)

	default:
		return true
	}
}

func mustHeapAlloc(n *Node) bool {
	// TODO(mdempsky): Cleanup this mess.
	return n.Type != nil &&
		(n.Type.Width > maxStackVarSize ||
			(n.Op == ONEW || n.Op == OPTRLIT) && n.Type.Elem().Width >= maxImplicitStackVarSize ||
			n.Op == OMAKESLICE && !isSmallMakeSlice(n))
}

func (e *EscState) esc(n *Node, parent *Node) {
	if n == nil {
		return
	}

	lno := setlineno(n)

	// ninit logically runs at a different loopdepth than the rest of the for loop.
	e.esclist(n.Ninit, n)

	if n.Op == OFOR || n.Op == OFORUNTIL || n.Op == ORANGE {
		e.loopdepth++
	}

	// type switch variables have no ODCL.
	// process type switch as declaration.
	// must happen before processing of switch body,
	// so before recursion.
	if n.Op == OSWITCH && n.Left != nil && n.Left.Op == OTYPESW {
		for _, cas := range n.List.Slice() { // cases
			// it.N().Rlist is the variable per case
			if cas.Rlist.Len() != 0 {
				e.nodeEscState(cas.Rlist.First()).Loopdepth = e.loopdepth
			}
		}
	}

	// Big stuff and non-constant-sized stuff escapes unconditionally.
	// "Big" conditions that were scattered around in walk have been
	// gathered here.
	if n.Esc != EscHeap && mustHeapAlloc(n) {
		// isSmallMakeSlice returns false for non-constant len/cap.
		// If that's the case, print a more accurate escape reason.
		var msgVerb, escapeMsg string
		if n.Op == OMAKESLICE && (!Isconst(n.Left, CTINT) || !Isconst(n.Right, CTINT)) {
			msgVerb, escapeMsg = "has ", "non-constant size"
		} else {
			msgVerb, escapeMsg = "is ", "too large for stack"
		}

		if Debug['m'] > 2 {
			Warnl(n.Pos, "%v "+msgVerb+escapeMsg, n)
		}
		n.Esc = EscHeap
		addrescapes(n)
		e.escassignSinkWhy(n, n, escapeMsg) // TODO category: tooLarge
	}

	e.esc(n.Left, n)

	if n.Op == ORANGE {
		// ORANGE node's Right is evaluated before the loop
		e.loopdepth--
	}

	e.esc(n.Right, n)

	if n.Op == ORANGE {
		e.loopdepth++
	}

	e.esclist(n.Nbody, n)
	e.esclist(n.List, n)
	e.esclist(n.Rlist, n)

	if n.Op == OFOR || n.Op == OFORUNTIL || n.Op == ORANGE {
		e.loopdepth--
	}

	if Debug['m'] > 2 {
		fmt.Printf("%v:[%d] %v esc: %v\n", linestr(lineno), e.loopdepth, funcSym(Curfn), n)
	}

opSwitch:
	switch n.Op {
	// Record loop depth at declaration.
	case ODCL:
		if n.Left != nil {
			e.nodeEscState(n.Left).Loopdepth = e.loopdepth
		}

	case OLABEL:
		switch asNode(n.Sym.Label) {
		case &nonlooping:
			if Debug['m'] > 2 {
				fmt.Printf("%v:%v non-looping label\n", linestr(lineno), n)
			}
		case &looping:
			if Debug['m'] > 2 {
				fmt.Printf("%v: %v looping label\n", linestr(lineno), n)
			}
			e.loopdepth++
		}

		n.Sym.Label = nil

	case ORANGE:
		if n.List.Len() >= 2 {
			// Everything but fixed array is a dereference.

			// If fixed array is really the address of fixed array,
			// it is also a dereference, because it is implicitly
			// dereferenced (see #12588)
			if n.Type.IsArray() &&
				!(n.Right.Type.IsPtr() && types.Identical(n.Right.Type.Elem(), n.Type)) {
				e.escassignWhyWhere(n.List.Second(), n.Right, "range", n)
			} else {
				e.escassignDereference(n.List.Second(), n.Right, e.stepAssignWhere(n.List.Second(), n.Right, "range-deref", n))
			}
		}

	case OSWITCH:
		if n.Left != nil && n.Left.Op == OTYPESW {
			for _, cas := range n.List.Slice() {
				// cases
				// n.Left.Right is the argument of the .(type),
				// it.N().Rlist is the variable per case
				if cas.Rlist.Len() != 0 {
					e.escassignWhyWhere(cas.Rlist.First(), n.Left.Right, "switch case", n)
				}
			}
		}

	case OAS, OASOP:
		// Filter out some no-op assignments for escape analysis.
		if isSelfAssign(n.Left, n.Right) {
			if Debug['m'] != 0 {
				Warnl(n.Pos, "%v ignoring self-assignment in %S", e.curfnSym(n), n)
			}
			break
		}

		e.escassign(n.Left, n.Right, e.stepAssignWhere(nil, nil, "", n))

	case OAS2: // x,y = a,b
		if n.List.Len() == n.Rlist.Len() {
			rs := n.Rlist.Slice()
			where := n
			for i, n := range n.List.Slice() {
				e.escassignWhyWhere(n, rs[i], "assign-pair", where)
			}
		}

	case OAS2RECV: // v, ok = <-ch
		e.escassignWhyWhere(n.List.First(), n.Rlist.First(), "assign-pair-receive", n)
	case OAS2MAPR: // v, ok = m[k]
		e.escassignWhyWhere(n.List.First(), n.Rlist.First(), "assign-pair-mapr", n)
	case OAS2DOTTYPE: // v, ok = x.(type)
		e.escassignWhyWhere(n.List.First(), n.Rlist.First(), "assign-pair-dot-type", n)

	case OSEND: // ch <- x
		e.escassignSinkWhy(n, n.Right, "send")

	case ODEFER:
		if e.loopdepth == 1 { // top level
			break
		}
		// arguments leak out of scope
		// TODO: leak to a dummy node instead
		// defer f(x) - f and x escape
		e.escassignSinkWhy(n, n.Left.Left, "defer func")
		e.escassignSinkWhy(n, n.Left.Right, "defer func ...") // ODDDARG for call
		for _, arg := range n.Left.List.Slice() {
			e.escassignSinkWhy(n, arg, "defer func arg")
		}

	case OGO:
		// go f(x) - f and x escape
		e.escassignSinkWhy(n, n.Left.Left, "go func")
		e.escassignSinkWhy(n, n.Left.Right, "go func ...") // ODDDARG for call
		for _, arg := range n.Left.List.Slice() {
			e.escassignSinkWhy(n, arg, "go func arg")
		}

	case OCALLMETH, OCALLFUNC, OCALLINTER:
		e.esccall(n, parent)

		// esccall already done on n.Rlist.First()
		// tie its Retval to n.List
	case OAS2FUNC: // x,y = f()
		rs := e.nodeEscState(n.Rlist.First()).Retval.Slice()
		where := n
		for i, n := range n.List.Slice() {
			if i >= len(rs) {
				break
			}
			e.escassignWhyWhere(n, rs[i], "assign-pair-func-call", where)
		}
		if n.List.Len() != len(rs) {
			Fatalf("esc oas2func")
		}

	case ORETURN:
		retList := n.List
		if retList.Len() == 1 && Curfn.Type.NumResults() > 1 {
			// OAS2FUNC in disguise
			// esccall already done on n.List.First()
			// tie e.nodeEscState(n.List.First()).Retval to Curfn.Func.Dcl PPARAMOUT's
			retList = e.nodeEscState(n.List.First()).Retval
		}

		i := 0
		for _, lrn := range Curfn.Func.Dcl {
			if i >= retList.Len() {
				break
			}
			if lrn.Op != ONAME || lrn.Class() != PPARAMOUT {
				continue
			}
			e.escassignWhyWhere(lrn, retList.Index(i), "return", n)
			i++
		}

		if i < retList.Len() {
			Fatalf("esc return list")
		}

		// Argument could leak through recover.
	case OPANIC:
		e.escassignSinkWhy(n, n.Left, "panic")

	case OAPPEND:
		if !n.IsDDD() {
			for _, nn := range n.List.Slice()[1:] {
				e.escassignSinkWhy(n, nn, "appended to slice") // lose track of assign to dereference
			}
		} else {
			// append(slice1, slice2...) -- slice2 itself does not escape, but contents do.
			slice2 := n.List.Second()
			e.escassignDereference(&e.theSink, slice2, e.stepAssignWhere(n, slice2, "appended slice...", n)) // lose track of assign of dereference
			if Debug['m'] > 3 {
				Warnl(n.Pos, "%v special treatment of append(slice1, slice2...) %S", e.curfnSym(n), n)
			}
		}
		e.escassignDereference(&e.theSink, n.List.First(), e.stepAssignWhere(n, n.List.First(), "appendee slice", n)) // The original elements are now leaked, too

	case OCOPY:
		e.escassignDereference(&e.theSink, n.Right, e.stepAssignWhere(n, n.Right, "copied slice", n)) // lose track of assign of dereference

	case OCONV, OCONVNOP:
		e.escassignWhyWhere(n, n.Left, "converted", n)

	case OCONVIFACE:
		e.track(n)
		e.escassignWhyWhere(n, n.Left, "interface-converted", n)

	case OARRAYLIT:
		// Link values to array
		for _, elt := range n.List.Slice() {
			if elt.Op == OKEY {
				elt = elt.Right
			}
			e.escassign(n, elt, e.stepAssignWhere(n, elt, "array literal element", n))
		}

	case OSLICELIT:
		// Slice is not leaked until proven otherwise
		e.track(n)
		// Link values to slice
		for _, elt := range n.List.Slice() {
			if elt.Op == OKEY {
				elt = elt.Right
			}
			e.escassign(n, elt, e.stepAssignWhere(n, elt, "slice literal element", n))
		}

		// Link values to struct.
	case OSTRUCTLIT:
		for _, elt := range n.List.Slice() {
			e.escassignWhyWhere(n, elt.Left, "struct literal element", n)
		}

	case OPTRLIT:
		e.track(n)

		// Link OSTRUCTLIT to OPTRLIT; if OPTRLIT escapes, OSTRUCTLIT elements do too.
		e.escassignWhyWhere(n, n.Left, "pointer literal [assign]", n)

	case OCALLPART:
		e.track(n)

		// Contents make it to memory, lose track.
		e.escassignSinkWhy(n, n.Left, "call part")

	case OMAPLIT:
		e.track(n)
		// Keys and values make it to memory, lose track.
		for _, elt := range n.List.Slice() {
			e.escassignSinkWhy(n, elt.Left, "map literal key")
			e.escassignSinkWhy(n, elt.Right, "map literal value")
		}

	case OCLOSURE:
		// Link addresses of captured variables to closure.
		for _, v := range n.Func.Closure.Func.Cvars.Slice() {
			if v.Op == OXXX { // unnamed out argument; see dcl.go:/^funcargs
				continue
			}
			a := v.Name.Defn
			if !v.Name.Byval() {
				a = nod(OADDR, a, nil)
				a.Pos = v.Pos
				e.nodeEscState(a).Loopdepth = e.loopdepth
				a = typecheck(a, ctxExpr)
			}

			e.escassignWhyWhere(n, a, "captured by a closure", n)
		}
		fallthrough

	case OMAKECHAN,
		OMAKEMAP,
		OMAKESLICE,
		ONEW,
		ORUNES2STR,
		OBYTES2STR,
		OSTR2RUNES,
		OSTR2BYTES,
		ORUNESTR:
		e.track(n)

	case OADDSTR:
		e.track(n)
		// Arguments of OADDSTR do not escape.

	case OADDR:
		// current loop depth is an upper bound on actual loop depth
		// of addressed value.
		e.track(n)

		// for &x, use loop depth of x if known.
		// it should always be known, but if not, be conservative
		// and keep the current loop depth.
		if n.Left.Op == ONAME {
			switch n.Left.Class() {
			// PPARAM is loop depth 1 always.
			// PPARAMOUT is loop depth 0 for writes
			// but considered loop depth 1 for address-of,
			// so that writing the address of one result
			// to another (or the same) result makes the
			// first result move to the heap.
			case PPARAM, PPARAMOUT:
				nE := e.nodeEscState(n)
				nE.Loopdepth = 1
				break opSwitch
			}
		}
		nE := e.nodeEscState(n)
		leftE := e.nodeEscState(n.Left)
		if leftE.Loopdepth != 0 {
			nE.Loopdepth = leftE.Loopdepth
		}

	case ODOT,
		ODOTPTR,
		OINDEX:
		// Propagate the loopdepth of t to t.field.
		if n.Left.Op != OLITERAL { // OLITERAL node doesn't have esc state
			e.nodeEscState(n).Loopdepth = e.nodeEscState(n.Left).Loopdepth
		}
	}

	lineno = lno
}

// escassignWhyWhere bundles a common case of
// escassign(e, dst, src, e.stepAssignWhere(dst, src, reason, where))
func (e *EscState) escassignWhyWhere(dst, src *Node, reason string, where *Node) {
	var step *EscStep
	if Debug['m'] != 0 {
		step = e.stepAssignWhere(dst, src, reason, where)
	}
	e.escassign(dst, src, step)
}

// escassignSinkWhy bundles a common case of
// escassign(e, &e.theSink, src, e.stepAssign(nil, dst, src, reason))
func (e *EscState) escassignSinkWhy(dst, src *Node, reason string) {
	var step *EscStep
	if Debug['m'] != 0 {
		step = e.stepAssign(nil, dst, src, reason)
	}
	e.escassign(&e.theSink, src, step)
}

// escassignSinkWhyWhere is escassignSinkWhy but includes a call site
// for accurate location reporting.
func (e *EscState) escassignSinkWhyWhere(dst, src *Node, reason string, call *Node) {
	var step *EscStep
	if Debug['m'] != 0 {
		step = e.stepAssignWhere(dst, src, reason, call)
	}
	e.escassign(&e.theSink, src, step)
}

// Assert that expr somehow gets assigned to dst, if non nil.  for
// dst==nil, any name node expr still must be marked as being
// evaluated in curfn.	For expr==nil, dst must still be examined for
// evaluations inside it (e.g *f(x) = y)
func (e *EscState) escassign(dst, src *Node, step *EscStep) {
	if dst.isBlank() || dst == nil || src == nil || src.Op == ONONAME || src.Op == OXXX {
		return
	}

	if Debug['m'] > 2 {
		fmt.Printf("%v:[%d] %v escassign: %S(%0j)[%v] = %S(%0j)[%v]\n",
			linestr(lineno), e.loopdepth, funcSym(Curfn),
			dst, dst, dst.Op,
			src, src, src.Op)
	}

	setlineno(dst)

	originalDst := dst
	dstwhy := "assigned"

	// Analyze lhs of assignment.
	// Replace dst with &e.theSink if we can't track it.
	switch dst.Op {
	default:
		Dump("dst", dst)
		Fatalf("escassign: unexpected dst")

	case OARRAYLIT,
		OSLICELIT,
		OCLOSURE,
		OCONV,
		OCONVIFACE,
		OCONVNOP,
		OMAPLIT,
		OSTRUCTLIT,
		OPTRLIT,
		ODDDARG,
		OCALLPART:

	case ONAME:
		if dst.Class() == PEXTERN {
			dstwhy = "assigned to top level variable"
			dst = &e.theSink
		}

	case ODOT: // treat "dst.x = src" as "dst = src"
		e.escassign(dst.Left, src, e.stepAssign(step, originalDst, src, "dot-equals"))
		return

	case OINDEX:
		if dst.Left.Type.IsArray() {
			e.escassign(dst.Left, src, e.stepAssign(step, originalDst, src, "array-element-equals"))
			return
		}

		dstwhy = "slice-element-equals"
		dst = &e.theSink // lose track of dereference

	case ODEREF:
		dstwhy = "star-equals"
		dst = &e.theSink // lose track of dereference

	case ODOTPTR:
		dstwhy = "star-dot-equals"
		dst = &e.theSink // lose track of dereference

		// lose track of key and value
	case OINDEXMAP:
		e.escassign(&e.theSink, dst.Right, e.stepAssign(nil, originalDst, src, "key of map put"))
		dstwhy = "value of map put"
		dst = &e.theSink
	}

	lno := setlineno(src)
	e.pdepth++

	switch src.Op {
	case OADDR, // dst = &x
		ODEREF,  // dst = *x
		ODOTPTR, // dst = (*x).f
		ONAME,
		ODDDARG,
		OPTRLIT,
		OARRAYLIT,
		OSLICELIT,
		OMAPLIT,
		OSTRUCTLIT,
		OMAKECHAN,
		OMAKEMAP,
		OMAKESLICE,
		ORUNES2STR,
		OBYTES2STR,
		OSTR2RUNES,
		OSTR2BYTES,
		OADDSTR,
		ONEW,
		OCALLPART,
		ORUNESTR,
		OCONVIFACE:
		e.escflows(dst, src, e.stepAssign(step, originalDst, src, dstwhy))

	case OCLOSURE:
		// OCLOSURE is lowered to OPTRLIT,
		// insert OADDR to account for the additional indirection.
		a := nod(OADDR, src, nil)
		a.Pos = src.Pos
		e.nodeEscState(a).Loopdepth = e.nodeEscState(src).Loopdepth
		a.Type = types.NewPtr(src.Type)
		e.escflows(dst, a, e.stepAssign(nil, originalDst, src, dstwhy))

	// Flowing multiple returns to a single dst happens when
	// analyzing "go f(g())": here g() flows to sink (issue 4529).
	case OCALLMETH, OCALLFUNC, OCALLINTER:
		for _, n := range e.nodeEscState(src).Retval.Slice() {
			e.escflows(dst, n, e.stepAssign(nil, originalDst, n, dstwhy))
		}

		// A non-pointer escaping from a struct does not concern us.
	case ODOT:
		if src.Type != nil && !types.Haspointers(src.Type) {
			break
		}
		fallthrough

		// Conversions, field access, slice all preserve the input value.
	case OCONV,
		OCONVNOP,
		ODOTMETH,
		// treat recv.meth as a value with recv in it, only happens in ODEFER and OGO
		// iface.method already leaks iface in esccall, no need to put in extra ODOTINTER edge here
		OSLICE,
		OSLICE3,
		OSLICEARR,
		OSLICE3ARR,
		OSLICESTR:
		// Conversions, field access, slice all preserve the input value.
		e.escassign(dst, src.Left, e.stepAssign(step, originalDst, src, dstwhy))

	case ODOTTYPE,
		ODOTTYPE2:
		if src.Type != nil && !types.Haspointers(src.Type) {
			break
		}
		e.escassign(dst, src.Left, e.stepAssign(step, originalDst, src, dstwhy))

	case OAPPEND:
		// Append returns first argument.
		// Subsequent arguments are already leaked because they are operands to append.
		e.escassign(dst, src.List.First(), e.stepAssign(step, dst, src.List.First(), dstwhy))

	case OINDEX:
		// Index of array preserves input value.
		if src.Left.Type.IsArray() {
			e.escassign(dst, src.Left, e.stepAssign(step, originalDst, src, dstwhy))
		} else {
			e.escflows(dst, src, e.stepAssign(step, originalDst, src, dstwhy))
		}

	// Might be pointer arithmetic, in which case
	// the operands flow into the result.
	// TODO(rsc): Decide what the story is here. This is unsettling.
	case OADD,
		OSUB,
		OOR,
		OXOR,
		OMUL,
		ODIV,
		OMOD,
		OLSH,
		ORSH,
		OAND,
		OANDNOT,
		OPLUS,
		ONEG,
		OBITNOT:
		e.escassign(dst, src.Left, e.stepAssign(step, originalDst, src, dstwhy))

		e.escassign(dst, src.Right, e.stepAssign(step, originalDst, src, dstwhy))
	}

	e.pdepth--
	lineno = lno
}

// Common case for escapes is 16 bits 000000000xxxEEEE
// where commonest cases for xxx encoding in-to-out pointer
//  flow are 000, 001, 010, 011  and EEEE is computed Esc bits.
// Note width of xxx depends on value of constant
// bitsPerOutputInTag -- expect 2 or 3, so in practice the
// tag cache array is 64 or 128 long. Some entries will
// never be populated.
var tags [1 << (bitsPerOutputInTag + EscReturnBits)]string

// mktag returns the string representation for an escape analysis tag.
func mktag(mask int) string {
	switch mask & EscMask {
	case EscNone, EscReturn:
	default:
		Fatalf("escape mktag")
	}

	if mask < len(tags) && tags[mask] != "" {
		return tags[mask]
	}

	s := fmt.Sprintf("esc:0x%x", mask)
	if mask < len(tags) {
		tags[mask] = s
	}
	return s
}

// parsetag decodes an escape analysis tag and returns the esc value.
func parsetag(note string) uint16 {
	if !strings.HasPrefix(note, "esc:") {
		return EscUnknown
	}
	n, _ := strconv.ParseInt(note[4:], 0, 0)
	em := uint16(n)
	if em == 0 {
		return EscNone
	}
	return em
}

// describeEscape returns a string describing the escape tag.
// The result is either one of {EscUnknown, EscNone, EscHeap} which all have no further annotation
// or a description of parameter flow, which takes the form of an optional "contentToHeap"
// indicating that the content of this parameter is leaked to the heap, followed by a sequence
// of level encodings separated by spaces, one for each parameter, where _ means no flow,
// = means direct flow, and N asterisks (*) encodes content (obtained by indirection) flow.
// e.g., "contentToHeap _ =" means that a parameter's content (one or more dereferences)
// escapes to the heap, the parameter does not leak to the first output, but does leak directly
// to the second output (and if there are more than two outputs, there is no flow to those.)
func describeEscape(em uint16) string {
	var s string
	switch em & EscMask {
	case EscUnknown:
		s = "EscUnknown"
	case EscNone:
		s = "EscNone"
	case EscHeap:
		s = "EscHeap"
	case EscReturn:
		s = "EscReturn"
	}
	if em&EscContentEscapes != 0 {
		if s != "" {
			s += " "
		}
		s += "contentToHeap"
	}
	for em >>= EscReturnBits; em != 0; em >>= bitsPerOutputInTag {
		// See encoding description above
		if s != "" {
			s += " "
		}
		switch embits := em & bitsMaskForTag; embits {
		case 0:
			s += "_"
		case 1:
			s += "="
		default:
			for i := uint16(0); i < embits-1; i++ {
				s += "*"
			}
		}

	}
	return s
}

// escassignfromtag models the input-to-output assignment flow of one of a function
// calls arguments, where the flow is encoded in "note".
func (e *EscState) escassignfromtag(note string, dsts Nodes, src, call *Node) uint16 {
	em := parsetag(note)
	if src.Op == OLITERAL {
		return em
	}

	if Debug['m'] > 3 {
		fmt.Printf("%v::assignfromtag:: src=%S, em=%s\n",
			linestr(lineno), src, describeEscape(em))
	}

	if em == EscUnknown {
		e.escassignSinkWhyWhere(src, src, "passed to call[argument escapes]", call)
		return em
	}

	if em == EscNone {
		return em
	}

	// If content inside parameter (reached via indirection)
	// escapes to heap, mark as such.
	if em&EscContentEscapes != 0 {
		e.escassign(&e.theSink, e.addDereference(src), e.stepAssignWhere(src, src, "passed to call[argument content escapes]", call))
	}

	em0 := em
	dstsi := 0
	for em >>= EscReturnBits; em != 0 && dstsi < dsts.Len(); em >>= bitsPerOutputInTag {
		// Prefer the lowest-level path to the reference (for escape purposes).
		// Two-bit encoding (for example. 1, 3, and 4 bits are other options)
		//  01 = 0-level
		//  10 = 1-level, (content escapes),
		//  11 = 2-level, (content of content escapes),
		embits := em & bitsMaskForTag
		if embits > 0 {
			n := src
			for i := uint16(0); i < embits-1; i++ {
				n = e.addDereference(n) // encode level>0 as indirections
			}
			e.escassign(dsts.Index(dstsi), n, e.stepAssignWhere(dsts.Index(dstsi), src, "passed-to-and-returned-from-call", call))
		}
		dstsi++
	}
	// If there are too many outputs to fit in the tag,
	// that is handled at the encoding end as EscHeap,
	// so there is no need to check here.

	if em != 0 && dstsi >= dsts.Len() {
		Fatalf("corrupt esc tag %q or messed up escretval list\n", note)
	}
	return em0
}

func (e *EscState) escassignDereference(dst *Node, src *Node, step *EscStep) {
	if src.Op == OLITERAL {
		return
	}
	e.escassign(dst, e.addDereference(src), step)
}

// addDereference constructs a suitable ODEREF note applied to src.
// Because this is for purposes of escape accounting, not execution,
// some semantically dubious node combinations are (currently) possible.
func (e *EscState) addDereference(n *Node) *Node {
	ind := nod(ODEREF, n, nil)
	e.nodeEscState(ind).Loopdepth = e.nodeEscState(n).Loopdepth
	ind.Pos = n.Pos
	t := n.Type
	if t.IsPtr() || t.IsSlice() {
		// This should model our own sloppy use of ODEREF to encode
		// decreasing levels of indirection; i.e., "indirecting" a slice
		// yields the type of an element.
		t = t.Elem()
	} else if t.IsString() {
		t = types.Types[TUINT8]
	}
	ind.Type = t
	return ind
}

// escNoteOutputParamFlow encodes maxEncodedLevel/.../1/0-level flow to the vargen'th parameter.
// Levels greater than maxEncodedLevel are replaced with maxEncodedLevel.
// If the encoding cannot describe the modified input level and output number, then EscHeap is returned.
func escNoteOutputParamFlow(e uint16, vargen int32, level Level) uint16 {
	// Flow+level is encoded in two bits.
	// 00 = not flow, xx = level+1 for 0 <= level <= maxEncodedLevel
	// 16 bits for Esc allows 6x2bits or 4x3bits or 3x4bits if additional information would be useful.
	if level.int() <= 0 && level.guaranteedDereference() > 0 {
		return escMax(e|EscContentEscapes, EscNone) // At least one deref, thus only content.
	}
	if level.int() < 0 {
		return EscHeap
	}
	if level.int() > maxEncodedLevel {
		// Cannot encode larger values than maxEncodedLevel.
		level = levelFrom(maxEncodedLevel)
	}
	encoded := uint16(level.int() + 1)

	shift := uint(bitsPerOutputInTag*(vargen-1) + EscReturnBits)
	old := (e >> shift) & bitsMaskForTag
	if old == 0 || encoded != 0 && encoded < old {
		old = encoded
	}

	encodedFlow := old << shift
	if (encodedFlow>>shift)&bitsMaskForTag != old {
		// Encoding failure defaults to heap.
		return EscHeap
	}

	return (e &^ (bitsMaskForTag << shift)) | encodedFlow
}

func (e *EscState) initEscRetval(call *Node, fntype *types.Type) {
	cE := e.nodeEscState(call)
	cE.Retval.Set(nil) // Suspect this is not nil for indirect calls.
	for i, f := range fntype.Results().Fields().Slice() {
		buf := fmt.Sprintf(".out%d", i)
		ret := newname(lookup(buf))
		ret.SetAddable(false) // TODO(mdempsky): Seems suspicious.
		ret.Type = f.Type
		ret.SetClass(PAUTO)
		ret.Name.Curfn = Curfn
		e.nodeEscState(ret).Loopdepth = e.loopdepth
		ret.Name.SetUsed(true)
		ret.Pos = call.Pos
		cE.Retval.Append(ret)
	}
}

// This is a bit messier than fortunate, pulled out of esc's big
// switch for clarity. We either have the paramnodes, which may be
// connected to other things through flows or we have the parameter type
// nodes, which may be marked "noescape". Navigating the ast is slightly
// different for methods vs plain functions and for imported vs
// this-package
func (e *EscState) esccall(call *Node, parent *Node) {
	var fntype *types.Type
	var indirect bool
	var fn *Node
	switch call.Op {
	default:
		Fatalf("esccall")

	case OCALLFUNC:
		fn = call.Left
		fntype = fn.Type
		indirect = fn.Op != ONAME || fn.Class() != PFUNC

	case OCALLMETH:
		fn = asNode(call.Left.Sym.Def)
		if fn != nil {
			fntype = fn.Type
		} else {
			fntype = call.Left.Type
		}

	case OCALLINTER:
		fntype = call.Left.Type
		indirect = true
	}

	argList := call.List
	args := argList.Slice()

	if indirect {
		// We know nothing!
		// Leak all the parameters
		for _, arg := range args {
			e.escassignSinkWhy(call, arg, "parameter to indirect call")
			if Debug['m'] > 3 {
				fmt.Printf("%v::esccall:: indirect call <- %S, untracked\n", linestr(lineno), arg)
			}
		}
		// Set up bogus outputs
		e.initEscRetval(call, fntype)
		// If there is a receiver, it also leaks to heap.
		if call.Op != OCALLFUNC {
			rf := fntype.Recv()
			r := call.Left.Left
			if types.Haspointers(rf.Type) {
				e.escassignSinkWhy(call, r, "receiver in indirect call")
			}
		} else { // indirect and OCALLFUNC = could be captured variables, too. (#14409)
			rets := e.nodeEscState(call).Retval.Slice()
			for _, ret := range rets {
				e.escassignDereference(ret, fn, e.stepAssignWhere(ret, fn, "captured by called closure", call))
			}
		}
		return
	}

	cE := e.nodeEscState(call)
	if fn != nil && fn.Op == ONAME && fn.Class() == PFUNC &&
		fn.Name.Defn != nil && fn.Name.Defn.Nbody.Len() != 0 && fn.Name.Param.Ntype != nil && fn.Name.Defn.Esc < EscFuncTagged {
		// function in same mutually recursive group. Incorporate into flow graph.
		if Debug['m'] > 3 {
			fmt.Printf("%v::esccall:: %S in recursive group\n", linestr(lineno), call)
		}

		if fn.Name.Defn.Esc == EscFuncUnknown || cE.Retval.Len() != 0 {
			Fatalf("graph inconsistency")
		}

		i := 0

		// Receiver.
		if call.Op != OCALLFUNC {
			rf := fntype.Recv()
			if rf.Sym != nil && !rf.Sym.IsBlank() {
				n := fn.Name.Defn.Func.Dcl[0]
				i++
				if n.Class() != PPARAM {
					Fatalf("esccall: not a parameter %+v", n)
				}
				e.escassignWhyWhere(n, call.Left.Left, "recursive call receiver", call)
			}
		}

		// Parameters.
		for _, param := range fntype.Params().FieldSlice() {
			if param.Sym == nil || param.Sym.IsBlank() {
				// Unnamed parameter is not listed in Func.Dcl.
				// But we need to consume the arg.
				if param.IsDDD() && !call.IsDDD() {
					args = nil
				} else {
					args = args[1:]
				}
				continue
			}

			n := fn.Name.Defn.Func.Dcl[i]
			i++
			if n.Class() != PPARAM {
				Fatalf("esccall: not a parameter %+v", n)
			}
			if len(args) == 0 {
				continue
			}
			arg := args[0]
			if n.IsDDD() && !call.IsDDD() {
				// Introduce ODDDARG node to represent ... allocation.
				arg = nod(ODDDARG, nil, nil)
				arr := types.NewArray(n.Type.Elem(), int64(len(args)))
				arg.Type = types.NewPtr(arr) // make pointer so it will be tracked
				arg.Pos = call.Pos
				e.track(arg)
				call.Right = arg
			}
			e.escassignWhyWhere(n, arg, "arg to recursive call", call) // TODO this message needs help.
			if arg == args[0] {
				args = args[1:]
				continue
			}
			// "..." arguments are untracked
			for _, a := range args {
				if Debug['m'] > 3 {
					fmt.Printf("%v::esccall:: ... <- %S, untracked\n", linestr(lineno), a)
				}
				e.escassignSinkWhyWhere(arg, a, "... arg to recursive call", call)
			}
			// ... arg consumes all remaining arguments
			args = nil
		}

		// Results.
		for _, n := range fn.Name.Defn.Func.Dcl[i:] {
			if n.Class() == PPARAMOUT {
				cE.Retval.Append(n)
			}
		}

		// Sanity check: all arguments must be consumed.
		if len(args) != 0 {
			Fatalf("esccall not consumed all args %+v\n", call)
		}
		return
	}

	// Imported or completely analyzed function. Use the escape tags.
	if cE.Retval.Len() != 0 {
		Fatalf("esc already decorated call %+v\n", call)
	}

	if Debug['m'] > 3 {
		fmt.Printf("%v::esccall:: %S not recursive\n", linestr(lineno), call)
	}

	// set up out list on this call node with dummy auto ONAMES in the current (calling) function.
	e.initEscRetval(call, fntype)

	// Receiver.
	if call.Op != OCALLFUNC {
		rf := fntype.Recv()
		r := call.Left.Left
		if types.Haspointers(rf.Type) {
			e.escassignfromtag(rf.Note, cE.Retval, r, call)
		}
	}

	for i, param := range fntype.Params().FieldSlice() {
		note := param.Note
		var arg *Node
		if param.IsDDD() && !call.IsDDD() {
			rest := args[i:]
			if len(rest) == 0 {
				break
			}

			// Introduce ODDDARG node to represent ... allocation.
			arg = nod(ODDDARG, nil, nil)
			arg.Pos = call.Pos
			arr := types.NewArray(param.Type.Elem(), int64(len(rest)))
			arg.Type = types.NewPtr(arr) // make pointer so it will be tracked
			e.track(arg)
			call.Right = arg

			// Store arguments into slice for ... arg.
			for _, a := range rest {
				if Debug['m'] > 3 {
					fmt.Printf("%v::esccall:: ... <- %S\n", linestr(lineno), a)
				}
				if note == uintptrEscapesTag {
					e.escassignSinkWhyWhere(arg, a, "arg to uintptrescapes ...", call)
				} else {
					e.escassignWhyWhere(arg, a, "arg to ...", call)
				}
			}
		} else {
			arg = args[i]
			if note == uintptrEscapesTag {
				e.escassignSinkWhy(arg, arg, "escaping uintptr")
			}
		}

		if types.Haspointers(param.Type) && e.escassignfromtag(note, cE.Retval, arg, call)&EscMask == EscNone && parent.Op != ODEFER && parent.Op != OGO {
			a := arg
			for a.Op == OCONVNOP {
				a = a.Left
			}
			switch a.Op {
			// The callee has already been analyzed, so its arguments have esc tags.
			// The argument is marked as not escaping at all.
			// Record that fact so that any temporary used for
			// synthesizing this expression can be reclaimed when
			// the function returns.
			// This 'noescape' is even stronger than the usual esc == EscNone.
			// arg.Esc == EscNone means that arg does not escape the current function.
			// arg.SetNoescape(true) here means that arg does not escape this statement
			// in the current function.
			case OCALLPART, OCLOSURE, ODDDARG, OARRAYLIT, OSLICELIT, OPTRLIT, OSTRUCTLIT:
				a.SetNoescape(true)
			}
		}
	}
}

// escflows records the link src->dst in dst, throwing out some quick wins,
// and also ensuring that dst is noted as a flow destination.
func (e *EscState) escflows(dst, src *Node, why *EscStep) {
	if dst == nil || src == nil || dst == src {
		return
	}

	// Don't bother building a graph for scalars.
	if src.Type != nil && !types.Haspointers(src.Type) && !isReflectHeaderDataField(src) {
		if Debug['m'] > 3 {
			fmt.Printf("%v::NOT flows:: %S <- %S\n", linestr(lineno), dst, src)
		}
		return
	}

	if Debug['m'] > 3 {
		fmt.Printf("%v::flows:: %S <- %S\n", linestr(lineno), dst, src)
	}

	dstE := e.nodeEscState(dst)
	if len(dstE.Flowsrc) == 0 {
		e.dsts = append(e.dsts, dst)
		e.dstcount++
	}

	e.edgecount++

	if why == nil {
		dstE.Flowsrc = append(dstE.Flowsrc, EscStep{src: src})
	} else {
		starwhy := *why
		starwhy.src = src // TODO: need to reconcile this w/ needs of explanations.
		dstE.Flowsrc = append(dstE.Flowsrc, starwhy)
	}
}

// Whenever we hit a reference node, the level goes up by one, and whenever
// we hit an OADDR, the level goes down by one. as long as we're on a level > 0
// finding an OADDR just means we're following the upstream of a dereference,
// so this address doesn't leak (yet).
// If level == 0, it means the /value/ of this node can reach the root of this flood.
// so if this node is an OADDR, its argument should be marked as escaping iff
// its currfn/e.loopdepth are different from the flood's root.
// Once an object has been moved to the heap, all of its upstream should be considered
// escaping to the global scope.
func (e *EscState) escflood(dst *Node) {
	switch dst.Op {
	case ONAME, OCLOSURE:
	default:
		return
	}

	dstE := e.nodeEscState(dst)
	if Debug['m'] > 2 {
		fmt.Printf("\nescflood:%d: dst %S scope:%v[%d]\n", e.walkgen, dst, e.curfnSym(dst), dstE.Loopdepth)
	}

	for i := range dstE.Flowsrc {
		e.walkgen++
		s := &dstE.Flowsrc[i]
		s.parent = nil
		e.escwalk(levelFrom(0), dst, s.src, s)
	}
}

// funcOutputAndInput reports whether dst and src correspond to output and input parameters of the same function.
func funcOutputAndInput(dst, src *Node) bool {
	// Note if dst is marked as escaping, then "returned" is too weak.
	return dst.Op == ONAME && dst.Class() == PPARAMOUT &&
		src.Op == ONAME && src.Class() == PPARAM && src.Name.Curfn == dst.Name.Curfn
}

func (es *EscStep) describe(src *Node) {
	if Debug['m'] < 2 {
		return
	}
	step0 := es
	for step := step0; step != nil && !step.busy; step = step.parent {
		// TODO: We get cycles. Trigger is i = &i (where var i interface{})
		step.busy = true
		// The trail is a little odd because of how the
		// graph is constructed.  The link to the current
		// Node is parent.src unless parent is nil in which
		// case it is step.dst.
		nextDest := step.parent
		dst := step.dst
		where := step.where
		if nextDest != nil {
			dst = nextDest.src
		}
		if where == nil {
			where = dst
		}
		Warnl(src.Pos, "\tfrom %v (%s) at %s", dst, step.why, where.Line())
	}
	for step := step0; step != nil && step.busy; step = step.parent {
		step.busy = false
	}
}

const NOTALOOPDEPTH = -1

func (e *EscState) escwalk(level Level, dst *Node, src *Node, step *EscStep) {
	e.escwalkBody(level, dst, src, step, NOTALOOPDEPTH)
}

func (e *EscState) escwalkBody(level Level, dst *Node, src *Node, step *EscStep, extraloopdepth int32) {
	if src.Op == OLITERAL {
		return
	}
	srcE := e.nodeEscState(src)
	if srcE.Walkgen == e.walkgen {
		// Esclevels are vectors, do not compare as integers,
		// and must use "min" of old and new to guarantee
		// convergence.
		level = level.min(srcE.Level)
		if level == srcE.Level {
			// Have we been here already with an extraloopdepth,
			// or is the extraloopdepth provided no improvement on
			// what's already been seen?
			if srcE.Maxextraloopdepth >= extraloopdepth || srcE.Loopdepth >= extraloopdepth {
				return
			}
			srcE.Maxextraloopdepth = extraloopdepth
		}
	} else { // srcE.Walkgen < e.walkgen -- first time, reset this.
		srcE.Maxextraloopdepth = NOTALOOPDEPTH
	}

	srcE.Walkgen = e.walkgen
	srcE.Level = level
	modSrcLoopdepth := srcE.Loopdepth

	if extraloopdepth > modSrcLoopdepth {
		modSrcLoopdepth = extraloopdepth
	}

	if Debug['m'] > 2 {
		fmt.Printf("escwalk: level:%d depth:%d %.*s op=%v %S(%0j) scope:%v[%d] extraloopdepth=%v\n",
			level, e.pdepth, e.pdepth, "\t\t\t\t\t\t\t\t\t\t", src.Op, src, src, e.curfnSym(src), srcE.Loopdepth, extraloopdepth)
	}

	e.pdepth++

	// Input parameter flowing to output parameter?
	var leaks bool
	var osrcesc uint16 // used to prevent duplicate error messages

	dstE := e.nodeEscState(dst)
	if funcOutputAndInput(dst, src) && src.Esc&EscMask < EscHeap && dst.Esc != EscHeap {
		// This case handles:
		// 1. return in
		// 2. return &in
		// 3. tmp := in; return &tmp
		// 4. return *in
		if Debug['m'] != 0 {
			if Debug['m'] <= 2 {
				Warnl(src.Pos, "leaking param: %S to result %v level=%v", src, dst.Sym, level.int())
				step.describe(src)
			} else {
				Warnl(src.Pos, "leaking param: %S to result %v level=%v", src, dst.Sym, level)
			}
		}
		if src.Esc&EscMask != EscReturn {
			src.Esc = EscReturn | src.Esc&EscContentEscapes
		}
		src.Esc = escNoteOutputParamFlow(src.Esc, dst.Name.Vargen, level)
		goto recurse
	}

	// If parameter content escapes to heap, set EscContentEscapes
	// Note minor confusion around escape from pointer-to-struct vs escape from struct
	if dst.Esc == EscHeap &&
		src.Op == ONAME && src.Class() == PPARAM && src.Esc&EscMask < EscHeap &&
		level.int() > 0 {
		src.Esc = escMax(EscContentEscapes|src.Esc, EscNone)
	}

	leaks = level.int() <= 0 && level.guaranteedDereference() <= 0 && dstE.Loopdepth < modSrcLoopdepth
	leaks = leaks || level.int() <= 0 && dst.Esc&EscMask == EscHeap

	osrcesc = src.Esc
	switch src.Op {
	case ONAME:
		if src.Class() == PPARAM && (leaks || dstE.Loopdepth < 0) && src.Esc&EscMask < EscHeap {
			if level.guaranteedDereference() > 0 {
				src.Esc = escMax(EscContentEscapes|src.Esc, EscNone)
				if Debug['m'] != 0 {
					if Debug['m'] <= 2 {
						if osrcesc != src.Esc {
							Warnl(src.Pos, "leaking param content: %S", src)
							step.describe(src)
						}
					} else {
						Warnl(src.Pos, "leaking param content: %S level=%v dst.eld=%v src.eld=%v dst=%S",
							src, level, dstE.Loopdepth, modSrcLoopdepth, dst)
					}
				}
			} else {
				src.Esc = EscHeap
				if Debug['m'] != 0 {
					if Debug['m'] <= 2 {
						Warnl(src.Pos, "leaking param: %S", src)
						step.describe(src)
					} else {
						Warnl(src.Pos, "leaking param: %S level=%v dst.eld=%v src.eld=%v dst=%S",
							src, level, dstE.Loopdepth, modSrcLoopdepth, dst)
					}
				}
			}
		}

		// Treat a captured closure variable as equivalent to the
		// original variable.
		if src.IsClosureVar() {
			e.escwalk(level, dst, src.Name.Defn, e.stepWalk(dst, src.Name.Defn, "closure-var", step))
		}

	case OPTRLIT, OADDR:
		why := "pointer literal"
		if src.Op == OADDR {
			why = "address-of"
		}
		if leaks {
			src.Esc = EscHeap
			if Debug['m'] != 0 && osrcesc != src.Esc && src.Op != OADDR {
				p := src
				if p.Left.Op == OCLOSURE {
					p = p.Left // merely to satisfy error messages in tests
				}
				if Debug['m'] > 2 {
					Warnl(src.Pos, "%S escapes to heap, level=%v, dst=%v dst.eld=%v, src.eld=%v",
						p, level, dst, dstE.Loopdepth, modSrcLoopdepth)
				} else {
					Warnl(src.Pos, "%S escapes to heap", p)
					step.describe(src)
				}
			}
			addrescapes(src.Left)
			e.escwalkBody(level.dec(), dst, src.Left, e.stepWalk(dst, src.Left, why, step), modSrcLoopdepth)
			extraloopdepth = modSrcLoopdepth // passes to recursive case, seems likely a no-op
		} else {
			e.escwalk(level.dec(), dst, src.Left, e.stepWalk(dst, src.Left, why, step))
		}

	case OAPPEND:
		e.escwalk(level, dst, src.List.First(), e.stepWalk(dst, src.List.First(), "append-first-arg", step))

	case ODDDARG:
		if leaks {
			src.Esc = EscHeap
			if Debug['m'] != 0 && osrcesc != src.Esc {
				Warnl(src.Pos, "%S escapes to heap", src)
				step.describe(src)
			}
			extraloopdepth = modSrcLoopdepth
		}
		// similar to a slice arraylit and its args.
		level = level.dec()

	case OSLICELIT:
		for _, elt := range src.List.Slice() {
			if elt.Op == OKEY {
				elt = elt.Right
			}
			e.escwalk(level.dec(), dst, elt, e.stepWalk(dst, elt, "slice-literal-element", step))
		}

		fallthrough

	case OMAKECHAN,
		OMAKEMAP,
		OMAKESLICE,
		ORUNES2STR,
		OBYTES2STR,
		OSTR2RUNES,
		OSTR2BYTES,
		OADDSTR,
		OMAPLIT,
		ONEW,
		OCLOSURE,
		OCALLPART,
		ORUNESTR,
		OCONVIFACE:
		if leaks {
			src.Esc = EscHeap
			if Debug['m'] != 0 && osrcesc != src.Esc {
				Warnl(src.Pos, "%S escapes to heap", src)
				step.describe(src)
			}
			extraloopdepth = modSrcLoopdepth
			if src.Op == OCONVIFACE {
				lt := src.Left.Type
				if !lt.IsInterface() && !isdirectiface(lt) && types.Haspointers(lt) {
					// We're converting from a non-direct interface type.
					// The interface will hold a heap copy of the data
					// (by calling convT2I or friend). Flow the data to heap.
					// See issue 29353.
					e.escwalk(level, &e.theSink, src.Left, e.stepWalk(dst, src.Left, "interface-converted", step))
				}
			}
		}

	case ODOT,
		ODOTTYPE:
		e.escwalk(level, dst, src.Left, e.stepWalk(dst, src.Left, "dot", step))

	case
		OSLICE,
		OSLICEARR,
		OSLICE3,
		OSLICE3ARR,
		OSLICESTR:
		e.escwalk(level, dst, src.Left, e.stepWalk(dst, src.Left, "slice", step))

	case OINDEX:
		if src.Left.Type.IsArray() {
			e.escwalk(level, dst, src.Left, e.stepWalk(dst, src.Left, "fixed-array-index-of", step))
			break
		}
		fallthrough

	case ODOTPTR:
		e.escwalk(level.inc(), dst, src.Left, e.stepWalk(dst, src.Left, "dot of pointer", step))
	case OINDEXMAP:
		e.escwalk(level.inc(), dst, src.Left, e.stepWalk(dst, src.Left, "map index", step))
	case ODEREF:
		e.escwalk(level.inc(), dst, src.Left, e.stepWalk(dst, src.Left, "indirection", step))

	// In this case a link went directly to a call, but should really go
	// to the dummy .outN outputs that were created for the call that
	// themselves link to the inputs with levels adjusted.
	// See e.g. #10466
	// This can only happen with functions returning a single result.
	case OCALLMETH, OCALLFUNC, OCALLINTER:
		if srcE.Retval.Len() != 0 {
			if Debug['m'] > 2 {
				fmt.Printf("%v:[%d] dst %S escwalk replace src: %S with %S\n",
					linestr(lineno), e.loopdepth,
					dst, src, srcE.Retval.First())
			}
			src = srcE.Retval.First()
			srcE = e.nodeEscState(src)
		}
	}

recurse:
	level = level.copy()

	for i := range srcE.Flowsrc {
		s := &srcE.Flowsrc[i]
		s.parent = step
		e.escwalkBody(level, dst, s.src, s, extraloopdepth)
		s.parent = nil
	}

	e.pdepth--
}

// addrescapes tags node n as having had its address taken
// by "increasing" the "value" of n.Esc to EscHeap.
// Storage is allocated as necessary to allow the address
// to be taken.
func addrescapes(n *Node) {
	switch n.Op {
	default:
		// Unexpected Op, probably due to a previous type error. Ignore.

	case ODEREF, ODOTPTR:
		// Nothing to do.

	case ONAME:
		if n == nodfp {
			break
		}

		// if this is a tmpname (PAUTO), it was tagged by tmpname as not escaping.
		// on PPARAM it means something different.
		if n.Class() == PAUTO && n.Esc == EscNever {
			break
		}

		// If a closure reference escapes, mark the outer variable as escaping.
		if n.IsClosureVar() {
			addrescapes(n.Name.Defn)
			break
		}

		if n.Class() != PPARAM && n.Class() != PPARAMOUT && n.Class() != PAUTO {
			break
		}

		// This is a plain parameter or local variable that needs to move to the heap,
		// but possibly for the function outside the one we're compiling.
		// That is, if we have:
		//
		//	func f(x int) {
		//		func() {
		//			global = &x
		//		}
		//	}
		//
		// then we're analyzing the inner closure but we need to move x to the
		// heap in f, not in the inner closure. Flip over to f before calling moveToHeap.
		oldfn := Curfn
		Curfn = n.Name.Curfn
		if Curfn.Func.Closure != nil && Curfn.Op == OCLOSURE {
			Curfn = Curfn.Func.Closure
		}
		ln := lineno
		lineno = Curfn.Pos
		moveToHeap(n)
		Curfn = oldfn
		lineno = ln

	// ODOTPTR has already been introduced,
	// so these are the non-pointer ODOT and OINDEX.
	// In &x[0], if x is a slice, then x does not
	// escape--the pointer inside x does, but that
	// is always a heap pointer anyway.
	case ODOT, OINDEX, OPAREN, OCONVNOP:
		if !n.Left.Type.IsSlice() {
			addrescapes(n.Left)
		}
	}
}

// moveToHeap records the parameter or local variable n as moved to the heap.
func moveToHeap(n *Node) {
	if Debug['r'] != 0 {
		Dump("MOVE", n)
	}
	if compiling_runtime {
		yyerror("%v escapes to heap, not allowed in runtime.", n)
	}
	if n.Class() == PAUTOHEAP {
		Dump("n", n)
		Fatalf("double move to heap")
	}

	// Allocate a local stack variable to hold the pointer to the heap copy.
	// temp will add it to the function declaration list automatically.
	heapaddr := temp(types.NewPtr(n.Type))
	heapaddr.Sym = lookup("&" + n.Sym.Name)
	heapaddr.Orig.Sym = heapaddr.Sym
	heapaddr.Pos = n.Pos

	// Unset AutoTemp to persist the &foo variable name through SSA to
	// liveness analysis.
	// TODO(mdempsky/drchase): Cleaner solution?
	heapaddr.Name.SetAutoTemp(false)

	// Parameters have a local stack copy used at function start/end
	// in addition to the copy in the heap that may live longer than
	// the function.
	if n.Class() == PPARAM || n.Class() == PPARAMOUT {
		if n.Xoffset == BADWIDTH {
			Fatalf("addrescapes before param assignment")
		}

		// We rewrite n below to be a heap variable (indirection of heapaddr).
		// Preserve a copy so we can still write code referring to the original,
		// and substitute that copy into the function declaration list
		// so that analyses of the local (on-stack) variables use it.
		stackcopy := newname(n.Sym)
		stackcopy.SetAddable(false)
		stackcopy.Type = n.Type
		stackcopy.Xoffset = n.Xoffset
		stackcopy.SetClass(n.Class())
		stackcopy.Name.Param.Heapaddr = heapaddr
		if n.Class() == PPARAMOUT {
			// Make sure the pointer to the heap copy is kept live throughout the function.
			// The function could panic at any point, and then a defer could recover.
			// Thus, we need the pointer to the heap copy always available so the
			// post-deferreturn code can copy the return value back to the stack.
			// See issue 16095.
			heapaddr.SetIsOutputParamHeapAddr(true)
		}
		n.Name.Param.Stackcopy = stackcopy

		// Substitute the stackcopy into the function variable list so that
		// liveness and other analyses use the underlying stack slot
		// and not the now-pseudo-variable n.
		found := false
		for i, d := range Curfn.Func.Dcl {
			if d == n {
				Curfn.Func.Dcl[i] = stackcopy
				found = true
				break
			}
			// Parameters are before locals, so can stop early.
			// This limits the search even in functions with many local variables.
			if d.Class() == PAUTO {
				break
			}
		}
		if !found {
			Fatalf("cannot find %v in local variable list", n)
		}
		Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
	}

	// Modify n in place so that uses of n now mean indirection of the heapaddr.
	n.SetClass(PAUTOHEAP)
	n.Xoffset = 0
	n.Name.Param.Heapaddr = heapaddr
	n.Esc = EscHeap
	if Debug['m'] != 0 {
		fmt.Printf("%v: moved to heap: %v\n", n.Line(), n)
	}
}

// This special tag is applied to uintptr variables
// that we believe may hold unsafe.Pointers for
// calls into assembly functions.
const unsafeUintptrTag = "unsafe-uintptr"

// This special tag is applied to uintptr parameters of functions
// marked go:uintptrescapes.
const uintptrEscapesTag = "uintptr-escapes"

func esctag(fn *Node) {
	fn.Esc = EscFuncTagged

	name := func(s *types.Sym, narg int) string {
		if s != nil {
			return s.Name
		}
		return fmt.Sprintf("arg#%d", narg)
	}

	// External functions are assumed unsafe,
	// unless //go:noescape is given before the declaration.
	if fn.Nbody.Len() == 0 {
		if fn.Noescape() {
			for _, f := range fn.Type.Params().Fields().Slice() {
				if types.Haspointers(f.Type) {
					f.Note = mktag(EscNone)
				}
			}
		}

		// Assume that uintptr arguments must be held live across the call.
		// This is most important for syscall.Syscall.
		// See golang.org/issue/13372.
		// This really doesn't have much to do with escape analysis per se,
		// but we are reusing the ability to annotate an individual function
		// argument and pass those annotations along to importing code.
		narg := 0
		for _, f := range fn.Type.Params().Fields().Slice() {
			narg++
			if f.Type.Etype == TUINTPTR {
				if Debug['m'] != 0 {
					Warnl(fn.Pos, "%v assuming %v is unsafe uintptr", funcSym(fn), name(f.Sym, narg))
				}
				f.Note = unsafeUintptrTag
			}
		}

		return
	}

	if fn.Func.Pragma&UintptrEscapes != 0 {
		narg := 0
		for _, f := range fn.Type.Params().Fields().Slice() {
			narg++
			if f.Type.Etype == TUINTPTR {
				if Debug['m'] != 0 {
					Warnl(fn.Pos, "%v marking %v as escaping uintptr", funcSym(fn), name(f.Sym, narg))
				}
				f.Note = uintptrEscapesTag
			}

			if f.IsDDD() && f.Type.Elem().Etype == TUINTPTR {
				// final argument is ...uintptr.
				if Debug['m'] != 0 {
					Warnl(fn.Pos, "%v marking %v as escaping ...uintptr", funcSym(fn), name(f.Sym, narg))
				}
				f.Note = uintptrEscapesTag
			}
		}
	}

	for _, fs := range types.RecvsParams {
		for _, f := range fs(fn.Type).Fields().Slice() {
			if !types.Haspointers(f.Type) { // don't bother tagging for scalars
				continue
			}
			if f.Note == uintptrEscapesTag {
				// Note is already set in the loop above.
				continue
			}

			// Unnamed parameters are unused and therefore do not escape.
			if f.Sym == nil || f.Sym.IsBlank() {
				f.Note = mktag(EscNone)
				continue
			}

			switch esc := asNode(f.Nname).Esc; esc & EscMask {
			case EscNone, // not touched by escflood
				EscReturn:
				f.Note = mktag(int(esc))

			case EscHeap: // touched by escflood, moved to heap
			}
		}
	}
}
