package pointer

// This file implements the generation and resolution rules for
// constraints arising from the use of reflection in the target
// program.  See doc.go for explanation of the representation.
//
// For consistency, the names of all parameters match those of the
// actual functions in the "reflect" package.
//
// To avoid proliferation of equivalent labels, intrinsics should
// memoize as much as possible, like TypeOf and Zero do for their
// tagged objects.
//
// TODO(adonovan): this file is rather subtle.  Explain how we derive
// the implementation of each reflect operator from its spec,
// including the subtleties of reflect.flag{Addr,RO,Indir}.
// [Hint: our implementation is as if reflect.flagIndir was always
// true, i.e. reflect.Values are pointers to tagged objects, there is
// no inline allocation optimization; and indirect tagged objects (not
// yet implemented) correspond to reflect.Values with
// reflect.flagAddr.]
// A picture would help too.
//
// TODO(adonovan): try factoring up the common parts of the majority of
// these constraints that are single input, single output.

import (
	"fmt"
	"reflect"

	"llvm.org/llgo/third_party/gotools/go/exact"
	"llvm.org/llgo/third_party/gotools/go/ssa"
	"llvm.org/llgo/third_party/gotools/go/types"
)

func init() {
	for name, fn := range map[string]intrinsic{
		// reflect.Value methods.
		"(reflect.Value).Addr":            ext۰reflect۰Value۰Addr,
		"(reflect.Value).Bool":            ext۰NoEffect,
		"(reflect.Value).Bytes":           ext۰reflect۰Value۰Bytes,
		"(reflect.Value).Call":            ext۰reflect۰Value۰Call,
		"(reflect.Value).CallSlice":       ext۰reflect۰Value۰CallSlice,
		"(reflect.Value).CanAddr":         ext۰NoEffect,
		"(reflect.Value).CanInterface":    ext۰NoEffect,
		"(reflect.Value).CanSet":          ext۰NoEffect,
		"(reflect.Value).Cap":             ext۰NoEffect,
		"(reflect.Value).Close":           ext۰NoEffect,
		"(reflect.Value).Complex":         ext۰NoEffect,
		"(reflect.Value).Convert":         ext۰reflect۰Value۰Convert,
		"(reflect.Value).Elem":            ext۰reflect۰Value۰Elem,
		"(reflect.Value).Field":           ext۰reflect۰Value۰Field,
		"(reflect.Value).FieldByIndex":    ext۰reflect۰Value۰FieldByIndex,
		"(reflect.Value).FieldByName":     ext۰reflect۰Value۰FieldByName,
		"(reflect.Value).FieldByNameFunc": ext۰reflect۰Value۰FieldByNameFunc,
		"(reflect.Value).Float":           ext۰NoEffect,
		"(reflect.Value).Index":           ext۰reflect۰Value۰Index,
		"(reflect.Value).Int":             ext۰NoEffect,
		"(reflect.Value).Interface":       ext۰reflect۰Value۰Interface,
		"(reflect.Value).InterfaceData":   ext۰NoEffect,
		"(reflect.Value).IsNil":           ext۰NoEffect,
		"(reflect.Value).IsValid":         ext۰NoEffect,
		"(reflect.Value).Kind":            ext۰NoEffect,
		"(reflect.Value).Len":             ext۰NoEffect,
		"(reflect.Value).MapIndex":        ext۰reflect۰Value۰MapIndex,
		"(reflect.Value).MapKeys":         ext۰reflect۰Value۰MapKeys,
		"(reflect.Value).Method":          ext۰reflect۰Value۰Method,
		"(reflect.Value).MethodByName":    ext۰reflect۰Value۰MethodByName,
		"(reflect.Value).NumField":        ext۰NoEffect,
		"(reflect.Value).NumMethod":       ext۰NoEffect,
		"(reflect.Value).OverflowComplex": ext۰NoEffect,
		"(reflect.Value).OverflowFloat":   ext۰NoEffect,
		"(reflect.Value).OverflowInt":     ext۰NoEffect,
		"(reflect.Value).OverflowUint":    ext۰NoEffect,
		"(reflect.Value).Pointer":         ext۰NoEffect,
		"(reflect.Value).Recv":            ext۰reflect۰Value۰Recv,
		"(reflect.Value).Send":            ext۰reflect۰Value۰Send,
		"(reflect.Value).Set":             ext۰reflect۰Value۰Set,
		"(reflect.Value).SetBool":         ext۰NoEffect,
		"(reflect.Value).SetBytes":        ext۰reflect۰Value۰SetBytes,
		"(reflect.Value).SetComplex":      ext۰NoEffect,
		"(reflect.Value).SetFloat":        ext۰NoEffect,
		"(reflect.Value).SetInt":          ext۰NoEffect,
		"(reflect.Value).SetLen":          ext۰NoEffect,
		"(reflect.Value).SetMapIndex":     ext۰reflect۰Value۰SetMapIndex,
		"(reflect.Value).SetPointer":      ext۰reflect۰Value۰SetPointer,
		"(reflect.Value).SetString":       ext۰NoEffect,
		"(reflect.Value).SetUint":         ext۰NoEffect,
		"(reflect.Value).Slice":           ext۰reflect۰Value۰Slice,
		"(reflect.Value).String":          ext۰NoEffect,
		"(reflect.Value).TryRecv":         ext۰reflect۰Value۰Recv,
		"(reflect.Value).TrySend":         ext۰reflect۰Value۰Send,
		"(reflect.Value).Type":            ext۰NoEffect,
		"(reflect.Value).Uint":            ext۰NoEffect,
		"(reflect.Value).UnsafeAddr":      ext۰NoEffect,

		// Standalone reflect.* functions.
		"reflect.Append":      ext۰reflect۰Append,
		"reflect.AppendSlice": ext۰reflect۰AppendSlice,
		"reflect.Copy":        ext۰reflect۰Copy,
		"reflect.ChanOf":      ext۰reflect۰ChanOf,
		"reflect.DeepEqual":   ext۰NoEffect,
		"reflect.Indirect":    ext۰reflect۰Indirect,
		"reflect.MakeChan":    ext۰reflect۰MakeChan,
		"reflect.MakeFunc":    ext۰reflect۰MakeFunc,
		"reflect.MakeMap":     ext۰reflect۰MakeMap,
		"reflect.MakeSlice":   ext۰reflect۰MakeSlice,
		"reflect.MapOf":       ext۰reflect۰MapOf,
		"reflect.New":         ext۰reflect۰New,
		"reflect.NewAt":       ext۰reflect۰NewAt,
		"reflect.PtrTo":       ext۰reflect۰PtrTo,
		"reflect.Select":      ext۰reflect۰Select,
		"reflect.SliceOf":     ext۰reflect۰SliceOf,
		"reflect.TypeOf":      ext۰reflect۰TypeOf,
		"reflect.ValueOf":     ext۰reflect۰ValueOf,
		"reflect.Zero":        ext۰reflect۰Zero,
		"reflect.init":        ext۰NoEffect,

		// *reflect.rtype methods
		"(*reflect.rtype).Align":           ext۰NoEffect,
		"(*reflect.rtype).AssignableTo":    ext۰NoEffect,
		"(*reflect.rtype).Bits":            ext۰NoEffect,
		"(*reflect.rtype).ChanDir":         ext۰NoEffect,
		"(*reflect.rtype).ConvertibleTo":   ext۰NoEffect,
		"(*reflect.rtype).Elem":            ext۰reflect۰rtype۰Elem,
		"(*reflect.rtype).Field":           ext۰reflect۰rtype۰Field,
		"(*reflect.rtype).FieldAlign":      ext۰NoEffect,
		"(*reflect.rtype).FieldByIndex":    ext۰reflect۰rtype۰FieldByIndex,
		"(*reflect.rtype).FieldByName":     ext۰reflect۰rtype۰FieldByName,
		"(*reflect.rtype).FieldByNameFunc": ext۰reflect۰rtype۰FieldByNameFunc,
		"(*reflect.rtype).Implements":      ext۰NoEffect,
		"(*reflect.rtype).In":              ext۰reflect۰rtype۰In,
		"(*reflect.rtype).IsVariadic":      ext۰NoEffect,
		"(*reflect.rtype).Key":             ext۰reflect۰rtype۰Key,
		"(*reflect.rtype).Kind":            ext۰NoEffect,
		"(*reflect.rtype).Len":             ext۰NoEffect,
		"(*reflect.rtype).Method":          ext۰reflect۰rtype۰Method,
		"(*reflect.rtype).MethodByName":    ext۰reflect۰rtype۰MethodByName,
		"(*reflect.rtype).Name":            ext۰NoEffect,
		"(*reflect.rtype).NumField":        ext۰NoEffect,
		"(*reflect.rtype).NumIn":           ext۰NoEffect,
		"(*reflect.rtype).NumMethod":       ext۰NoEffect,
		"(*reflect.rtype).NumOut":          ext۰NoEffect,
		"(*reflect.rtype).Out":             ext۰reflect۰rtype۰Out,
		"(*reflect.rtype).PkgPath":         ext۰NoEffect,
		"(*reflect.rtype).Size":            ext۰NoEffect,
		"(*reflect.rtype).String":          ext۰NoEffect,
	} {
		intrinsicsByName[name] = fn
	}
}

// -------------------- (reflect.Value) --------------------

func ext۰reflect۰Value۰Addr(a *analysis, cgn *cgnode) {} // TODO(adonovan)

// ---------- func (Value).Bytes() Value ----------

// result = v.Bytes()
type rVBytesConstraint struct {
	v      nodeid // (ptr)
	result nodeid // (indirect)
}

func (c *rVBytesConstraint) ptr() nodeid { return c.v }
func (c *rVBytesConstraint) presolve(h *hvn) {
	h.markIndirect(onodeid(c.result), "rVBytes.result")
}
func (c *rVBytesConstraint) renumber(mapping []nodeid) {
	c.v = mapping[c.v]
	c.result = mapping[c.result]
}

func (c *rVBytesConstraint) String() string {
	return fmt.Sprintf("n%d = reflect n%d.Bytes()", c.result, c.v)
}

func (c *rVBytesConstraint) solve(a *analysis, delta *nodeset) {
	changed := false
	for _, x := range delta.AppendTo(a.deltaSpace) {
		vObj := nodeid(x)
		tDyn, slice, indirect := a.taggedValue(vObj)
		if indirect {
			// TODO(adonovan): we'll need to implement this
			// when we start creating indirect tagged objects.
			panic("indirect tagged object")
		}

		tSlice, ok := tDyn.Underlying().(*types.Slice)
		if ok && types.Identical(tSlice.Elem(), types.Typ[types.Uint8]) {
			if a.onlineCopy(c.result, slice) {
				changed = true
			}
		}
	}
	if changed {
		a.addWork(c.result)
	}
}

func ext۰reflect۰Value۰Bytes(a *analysis, cgn *cgnode) {
	a.addConstraint(&rVBytesConstraint{
		v:      a.funcParams(cgn.obj),
		result: a.funcResults(cgn.obj),
	})
}

// ---------- func (Value).Call(in []Value) []Value ----------

// result = v.Call(in)
type rVCallConstraint struct {
	cgn       *cgnode
	targets   nodeid // (indirect)
	v         nodeid // (ptr)
	arg       nodeid // = in[*]
	result    nodeid // (indirect)
	dotdotdot bool   // interpret last arg as a "..." slice
}

func (c *rVCallConstraint) ptr() nodeid { return c.v }
func (c *rVCallConstraint) presolve(h *hvn) {
	h.markIndirect(onodeid(c.targets), "rVCall.targets")
	h.markIndirect(onodeid(c.result), "rVCall.result")
}
func (c *rVCallConstraint) renumber(mapping []nodeid) {
	c.targets = mapping[c.targets]
	c.v = mapping[c.v]
	c.arg = mapping[c.arg]
	c.result = mapping[c.result]
}

func (c *rVCallConstraint) String() string {
	return fmt.Sprintf("n%d = reflect n%d.Call(n%d)", c.result, c.v, c.arg)
}

func (c *rVCallConstraint) solve(a *analysis, delta *nodeset) {
	if c.targets == 0 {
		panic("no targets")
	}

	changed := false
	for _, x := range delta.AppendTo(a.deltaSpace) {
		vObj := nodeid(x)
		tDyn, fn, indirect := a.taggedValue(vObj)
		if indirect {
			// TODO(adonovan): we'll need to implement this
			// when we start creating indirect tagged objects.
			panic("indirect tagged object")
		}

		tSig, ok := tDyn.Underlying().(*types.Signature)
		if !ok {
			continue // not a function
		}
		if tSig.Recv() != nil {
			panic(tSig) // TODO(adonovan): rethink when we implement Method()
		}

		// Add dynamic call target.
		if a.onlineCopy(c.targets, fn) {
			a.addWork(c.targets)
			// TODO(adonovan): is 'else continue' a sound optimisation here?
		}

		// Allocate a P/R block.
		tParams := tSig.Params()
		tResults := tSig.Results()
		params := a.addNodes(tParams, "rVCall.params")
		results := a.addNodes(tResults, "rVCall.results")

		// Make a dynamic call to 'fn'.
		a.store(fn, params, 1, a.sizeof(tParams))
		a.load(results, fn, 1+a.sizeof(tParams), a.sizeof(tResults))

		// Populate P by type-asserting each actual arg (all merged in c.arg).
		for i, n := 0, tParams.Len(); i < n; i++ {
			T := tParams.At(i).Type()
			a.typeAssert(T, params, c.arg, false)
			params += nodeid(a.sizeof(T))
		}

		// Use R by tagging and copying each actual result to c.result.
		for i, n := 0, tResults.Len(); i < n; i++ {
			T := tResults.At(i).Type()
			// Convert from an arbitrary type to a reflect.Value
			// (like MakeInterface followed by reflect.ValueOf).
			if isInterface(T) {
				// (don't tag)
				if a.onlineCopy(c.result, results) {
					changed = true
				}
			} else {
				obj := a.makeTagged(T, c.cgn, nil)
				a.onlineCopyN(obj+1, results, a.sizeof(T))
				if a.addLabel(c.result, obj) { // (true)
					changed = true
				}
			}
			results += nodeid(a.sizeof(T))
		}
	}
	if changed {
		a.addWork(c.result)
	}
}

// Common code for direct (inlined) and indirect calls to (reflect.Value).Call.
func reflectCallImpl(a *analysis, cgn *cgnode, site *callsite, recv, arg nodeid, dotdotdot bool) nodeid {
	// Allocate []reflect.Value array for the result.
	ret := a.nextNode()
	a.addNodes(types.NewArray(a.reflectValueObj.Type(), 1), "rVCall.ret")
	a.endObject(ret, cgn, nil)

	// pts(targets) will be the set of possible call targets.
	site.targets = a.addOneNode(tInvalid, "rvCall.targets", nil)

	// All arguments are merged since they arrive in a slice.
	argelts := a.addOneNode(a.reflectValueObj.Type(), "rVCall.args", nil)
	a.load(argelts, arg, 1, 1) // slice elements

	a.addConstraint(&rVCallConstraint{
		cgn:       cgn,
		targets:   site.targets,
		v:         recv,
		arg:       argelts,
		result:    ret + 1, // results go into elements of ret
		dotdotdot: dotdotdot,
	})
	return ret
}

func reflectCall(a *analysis, cgn *cgnode, dotdotdot bool) {
	// This is the shared contour implementation of (reflect.Value).Call
	// and CallSlice, as used by indirect calls (rare).
	// Direct calls are inlined in gen.go, eliding the
	// intermediate cgnode for Call.
	site := new(callsite)
	cgn.sites = append(cgn.sites, site)
	recv := a.funcParams(cgn.obj)
	arg := recv + 1
	ret := reflectCallImpl(a, cgn, site, recv, arg, dotdotdot)
	a.addressOf(cgn.fn.Signature.Results().At(0).Type(), a.funcResults(cgn.obj), ret)
}

func ext۰reflect۰Value۰Call(a *analysis, cgn *cgnode) {
	reflectCall(a, cgn, false)
}

func ext۰reflect۰Value۰CallSlice(a *analysis, cgn *cgnode) {
	// TODO(adonovan): implement.  Also, inline direct calls in gen.go too.
	if false {
		reflectCall(a, cgn, true)
	}
}

func ext۰reflect۰Value۰Convert(a *analysis, cgn *cgnode) {} // TODO(adonovan)

// ---------- func (Value).Elem() Value ----------

// result = v.Elem()
type rVElemConstraint struct {
	cgn    *cgnode
	v      nodeid // (ptr)
	result nodeid // (indirect)
}

func (c *rVElemConstraint) ptr() nodeid { return c.v }
func (c *rVElemConstraint) presolve(h *hvn) {
	h.markIndirect(onodeid(c.result), "rVElem.result")
}
func (c *rVElemConstraint) renumber(mapping []nodeid) {
	c.v = mapping[c.v]
	c.result = mapping[c.result]
}

func (c *rVElemConstraint) String() string {
	return fmt.Sprintf("n%d = reflect n%d.Elem()", c.result, c.v)
}

func (c *rVElemConstraint) solve(a *analysis, delta *nodeset) {
	changed := false
	for _, x := range delta.AppendTo(a.deltaSpace) {
		vObj := nodeid(x)
		tDyn, payload, indirect := a.taggedValue(vObj)
		if indirect {
			// TODO(adonovan): we'll need to implement this
			// when we start creating indirect tagged objects.
			panic("indirect tagged object")
		}

		switch t := tDyn.Underlying().(type) {
		case *types.Interface:
			if a.onlineCopy(c.result, payload) {
				changed = true
			}

		case *types.Pointer:
			obj := a.makeTagged(t.Elem(), c.cgn, nil)
			a.load(obj+1, payload, 0, a.sizeof(t.Elem()))
			if a.addLabel(c.result, obj) {
				changed = true
			}
		}
	}
	if changed {
		a.addWork(c.result)
	}
}

func ext۰reflect۰Value۰Elem(a *analysis, cgn *cgnode) {
	a.addConstraint(&rVElemConstraint{
		cgn:    cgn,
		v:      a.funcParams(cgn.obj),
		result: a.funcResults(cgn.obj),
	})
}

func ext۰reflect۰Value۰Field(a *analysis, cgn *cgnode)           {} // TODO(adonovan)
func ext۰reflect۰Value۰FieldByIndex(a *analysis, cgn *cgnode)    {} // TODO(adonovan)
func ext۰reflect۰Value۰FieldByName(a *analysis, cgn *cgnode)     {} // TODO(adonovan)
func ext۰reflect۰Value۰FieldByNameFunc(a *analysis, cgn *cgnode) {} // TODO(adonovan)

// ---------- func (Value).Index() Value ----------

// result = v.Index()
type rVIndexConstraint struct {
	cgn    *cgnode
	v      nodeid // (ptr)
	result nodeid // (indirect)
}

func (c *rVIndexConstraint) ptr() nodeid { return c.v }
func (c *rVIndexConstraint) presolve(h *hvn) {
	h.markIndirect(onodeid(c.result), "rVIndex.result")
}
func (c *rVIndexConstraint) renumber(mapping []nodeid) {
	c.v = mapping[c.v]
	c.result = mapping[c.result]
}

func (c *rVIndexConstraint) String() string {
	return fmt.Sprintf("n%d = reflect n%d.Index()", c.result, c.v)
}

func (c *rVIndexConstraint) solve(a *analysis, delta *nodeset) {
	changed := false
	for _, x := range delta.AppendTo(a.deltaSpace) {
		vObj := nodeid(x)
		tDyn, payload, indirect := a.taggedValue(vObj)
		if indirect {
			// TODO(adonovan): we'll need to implement this
			// when we start creating indirect tagged objects.
			panic("indirect tagged object")
		}

		var res nodeid
		switch t := tDyn.Underlying().(type) {
		case *types.Array:
			res = a.makeTagged(t.Elem(), c.cgn, nil)
			a.onlineCopyN(res+1, payload+1, a.sizeof(t.Elem()))

		case *types.Slice:
			res = a.makeTagged(t.Elem(), c.cgn, nil)
			a.load(res+1, payload, 1, a.sizeof(t.Elem()))

		case *types.Basic:
			if t.Kind() == types.String {
				res = a.makeTagged(types.Typ[types.Rune], c.cgn, nil)
			}
		}
		if res != 0 && a.addLabel(c.result, res) {
			changed = true
		}
	}
	if changed {
		a.addWork(c.result)
	}
}

func ext۰reflect۰Value۰Index(a *analysis, cgn *cgnode) {
	a.addConstraint(&rVIndexConstraint{
		cgn:    cgn,
		v:      a.funcParams(cgn.obj),
		result: a.funcResults(cgn.obj),
	})
}

// ---------- func (Value).Interface() Value ----------

// result = v.Interface()
type rVInterfaceConstraint struct {
	v      nodeid // (ptr)
	result nodeid // (indirect)
}

func (c *rVInterfaceConstraint) ptr() nodeid { return c.v }
func (c *rVInterfaceConstraint) presolve(h *hvn) {
	h.markIndirect(onodeid(c.result), "rVInterface.result")
}
func (c *rVInterfaceConstraint) renumber(mapping []nodeid) {
	c.v = mapping[c.v]
	c.result = mapping[c.result]
}

func (c *rVInterfaceConstraint) String() string {
	return fmt.Sprintf("n%d = reflect n%d.Interface()", c.result, c.v)
}

func (c *rVInterfaceConstraint) solve(a *analysis, delta *nodeset) {
	changed := false
	for _, x := range delta.AppendTo(a.deltaSpace) {
		vObj := nodeid(x)
		tDyn, payload, indirect := a.taggedValue(vObj)
		if indirect {
			// TODO(adonovan): we'll need to implement this
			// when we start creating indirect tagged objects.
			panic("indirect tagged object")
		}

		if isInterface(tDyn) {
			if a.onlineCopy(c.result, payload) {
				a.addWork(c.result)
			}
		} else {
			if a.addLabel(c.result, vObj) {
				changed = true
			}
		}
	}
	if changed {
		a.addWork(c.result)
	}
}

func ext۰reflect۰Value۰Interface(a *analysis, cgn *cgnode) {
	a.addConstraint(&rVInterfaceConstraint{
		v:      a.funcParams(cgn.obj),
		result: a.funcResults(cgn.obj),
	})
}

// ---------- func (Value).MapIndex(Value) Value ----------

// result = v.MapIndex(_)
type rVMapIndexConstraint struct {
	cgn    *cgnode
	v      nodeid // (ptr)
	result nodeid // (indirect)
}

func (c *rVMapIndexConstraint) ptr() nodeid { return c.v }
func (c *rVMapIndexConstraint) presolve(h *hvn) {
	h.markIndirect(onodeid(c.result), "rVMapIndex.result")
}
func (c *rVMapIndexConstraint) renumber(mapping []nodeid) {
	c.v = mapping[c.v]
	c.result = mapping[c.result]
}

func (c *rVMapIndexConstraint) String() string {
	return fmt.Sprintf("n%d = reflect n%d.MapIndex(_)", c.result, c.v)
}

func (c *rVMapIndexConstraint) solve(a *analysis, delta *nodeset) {
	changed := false
	for _, x := range delta.AppendTo(a.deltaSpace) {
		vObj := nodeid(x)
		tDyn, m, indirect := a.taggedValue(vObj)
		tMap, _ := tDyn.Underlying().(*types.Map)
		if tMap == nil {
			continue // not a map
		}
		if indirect {
			// TODO(adonovan): we'll need to implement this
			// when we start creating indirect tagged objects.
			panic("indirect tagged object")
		}

		obj := a.makeTagged(tMap.Elem(), c.cgn, nil)
		a.load(obj+1, m, a.sizeof(tMap.Key()), a.sizeof(tMap.Elem()))
		if a.addLabel(c.result, obj) {
			changed = true
		}
	}
	if changed {
		a.addWork(c.result)
	}
}

func ext۰reflect۰Value۰MapIndex(a *analysis, cgn *cgnode) {
	a.addConstraint(&rVMapIndexConstraint{
		cgn:    cgn,
		v:      a.funcParams(cgn.obj),
		result: a.funcResults(cgn.obj),
	})
}

// ---------- func (Value).MapKeys() []Value ----------

// result = v.MapKeys()
type rVMapKeysConstraint struct {
	cgn    *cgnode
	v      nodeid // (ptr)
	result nodeid // (indirect)
}

func (c *rVMapKeysConstraint) ptr() nodeid { return c.v }
func (c *rVMapKeysConstraint) presolve(h *hvn) {
	h.markIndirect(onodeid(c.result), "rVMapKeys.result")
}
func (c *rVMapKeysConstraint) renumber(mapping []nodeid) {
	c.v = mapping[c.v]
	c.result = mapping[c.result]
}

func (c *rVMapKeysConstraint) String() string {
	return fmt.Sprintf("n%d = reflect n%d.MapKeys()", c.result, c.v)
}

func (c *rVMapKeysConstraint) solve(a *analysis, delta *nodeset) {
	changed := false
	for _, x := range delta.AppendTo(a.deltaSpace) {
		vObj := nodeid(x)
		tDyn, m, indirect := a.taggedValue(vObj)
		tMap, _ := tDyn.Underlying().(*types.Map)
		if tMap == nil {
			continue // not a map
		}
		if indirect {
			// TODO(adonovan): we'll need to implement this
			// when we start creating indirect tagged objects.
			panic("indirect tagged object")
		}

		kObj := a.makeTagged(tMap.Key(), c.cgn, nil)
		a.load(kObj+1, m, 0, a.sizeof(tMap.Key()))
		if a.addLabel(c.result, kObj) {
			changed = true
		}
	}
	if changed {
		a.addWork(c.result)
	}
}

func ext۰reflect۰Value۰MapKeys(a *analysis, cgn *cgnode) {
	// Allocate an array for the result.
	obj := a.nextNode()
	T := types.NewSlice(a.reflectValueObj.Type())
	a.addNodes(sliceToArray(T), "reflect.MapKeys result")
	a.endObject(obj, cgn, nil)
	a.addressOf(T, a.funcResults(cgn.obj), obj)

	a.addConstraint(&rVMapKeysConstraint{
		cgn:    cgn,
		v:      a.funcParams(cgn.obj),
		result: obj + 1, // result is stored in array elems
	})
}

func ext۰reflect۰Value۰Method(a *analysis, cgn *cgnode)       {} // TODO(adonovan)
func ext۰reflect۰Value۰MethodByName(a *analysis, cgn *cgnode) {} // TODO(adonovan)

// ---------- func (Value).Recv(Value) Value ----------

// result, _ = v.Recv()
type rVRecvConstraint struct {
	cgn    *cgnode
	v      nodeid // (ptr)
	result nodeid // (indirect)
}

func (c *rVRecvConstraint) ptr() nodeid { return c.v }
func (c *rVRecvConstraint) presolve(h *hvn) {
	h.markIndirect(onodeid(c.result), "rVRecv.result")
}
func (c *rVRecvConstraint) renumber(mapping []nodeid) {
	c.v = mapping[c.v]
	c.result = mapping[c.result]
}

func (c *rVRecvConstraint) String() string {
	return fmt.Sprintf("n%d = reflect n%d.Recv()", c.result, c.v)
}

func (c *rVRecvConstraint) solve(a *analysis, delta *nodeset) {
	changed := false
	for _, x := range delta.AppendTo(a.deltaSpace) {
		vObj := nodeid(x)
		tDyn, ch, indirect := a.taggedValue(vObj)
		tChan, _ := tDyn.Underlying().(*types.Chan)
		if tChan == nil {
			continue // not a channel
		}
		if indirect {
			// TODO(adonovan): we'll need to implement this
			// when we start creating indirect tagged objects.
			panic("indirect tagged object")
		}

		tElem := tChan.Elem()
		elemObj := a.makeTagged(tElem, c.cgn, nil)
		a.load(elemObj+1, ch, 0, a.sizeof(tElem))
		if a.addLabel(c.result, elemObj) {
			changed = true
		}
	}
	if changed {
		a.addWork(c.result)
	}
}

func ext۰reflect۰Value۰Recv(a *analysis, cgn *cgnode) {
	a.addConstraint(&rVRecvConstraint{
		cgn:    cgn,
		v:      a.funcParams(cgn.obj),
		result: a.funcResults(cgn.obj),
	})
}

// ---------- func (Value).Send(Value) ----------

// v.Send(x)
type rVSendConstraint struct {
	cgn *cgnode
	v   nodeid // (ptr)
	x   nodeid
}

func (c *rVSendConstraint) ptr() nodeid   { return c.v }
func (c *rVSendConstraint) presolve(*hvn) {}
func (c *rVSendConstraint) renumber(mapping []nodeid) {
	c.v = mapping[c.v]
	c.x = mapping[c.x]
}

func (c *rVSendConstraint) String() string {
	return fmt.Sprintf("reflect n%d.Send(n%d)", c.v, c.x)
}

func (c *rVSendConstraint) solve(a *analysis, delta *nodeset) {
	for _, x := range delta.AppendTo(a.deltaSpace) {
		vObj := nodeid(x)
		tDyn, ch, indirect := a.taggedValue(vObj)
		tChan, _ := tDyn.Underlying().(*types.Chan)
		if tChan == nil {
			continue // not a channel
		}
		if indirect {
			// TODO(adonovan): we'll need to implement this
			// when we start creating indirect tagged objects.
			panic("indirect tagged object")
		}

		// Extract x's payload to xtmp, then store to channel.
		tElem := tChan.Elem()
		xtmp := a.addNodes(tElem, "Send.xtmp")
		a.typeAssert(tElem, xtmp, c.x, false)
		a.store(ch, xtmp, 0, a.sizeof(tElem))
	}
}

func ext۰reflect۰Value۰Send(a *analysis, cgn *cgnode) {
	params := a.funcParams(cgn.obj)
	a.addConstraint(&rVSendConstraint{
		cgn: cgn,
		v:   params,
		x:   params + 1,
	})
}

func ext۰reflect۰Value۰Set(a *analysis, cgn *cgnode) {} // TODO(adonovan)

// ---------- func (Value).SetBytes(x []byte) ----------

// v.SetBytes(x)
type rVSetBytesConstraint struct {
	cgn *cgnode
	v   nodeid // (ptr)
	x   nodeid
}

func (c *rVSetBytesConstraint) ptr() nodeid   { return c.v }
func (c *rVSetBytesConstraint) presolve(*hvn) {}
func (c *rVSetBytesConstraint) renumber(mapping []nodeid) {
	c.v = mapping[c.v]
	c.x = mapping[c.x]
}

func (c *rVSetBytesConstraint) String() string {
	return fmt.Sprintf("reflect n%d.SetBytes(n%d)", c.v, c.x)
}

func (c *rVSetBytesConstraint) solve(a *analysis, delta *nodeset) {
	for _, x := range delta.AppendTo(a.deltaSpace) {
		vObj := nodeid(x)
		tDyn, slice, indirect := a.taggedValue(vObj)
		if indirect {
			// TODO(adonovan): we'll need to implement this
			// when we start creating indirect tagged objects.
			panic("indirect tagged object")
		}

		tSlice, ok := tDyn.Underlying().(*types.Slice)
		if ok && types.Identical(tSlice.Elem(), types.Typ[types.Uint8]) {
			if a.onlineCopy(slice, c.x) {
				a.addWork(slice)
			}
		}
	}
}

func ext۰reflect۰Value۰SetBytes(a *analysis, cgn *cgnode) {
	params := a.funcParams(cgn.obj)
	a.addConstraint(&rVSetBytesConstraint{
		cgn: cgn,
		v:   params,
		x:   params + 1,
	})
}

// ---------- func (Value).SetMapIndex(k Value, v Value) ----------

// v.SetMapIndex(key, val)
type rVSetMapIndexConstraint struct {
	cgn *cgnode
	v   nodeid // (ptr)
	key nodeid
	val nodeid
}

func (c *rVSetMapIndexConstraint) ptr() nodeid   { return c.v }
func (c *rVSetMapIndexConstraint) presolve(*hvn) {}
func (c *rVSetMapIndexConstraint) renumber(mapping []nodeid) {
	c.v = mapping[c.v]
	c.key = mapping[c.key]
	c.val = mapping[c.val]
}

func (c *rVSetMapIndexConstraint) String() string {
	return fmt.Sprintf("reflect n%d.SetMapIndex(n%d, n%d)", c.v, c.key, c.val)
}

func (c *rVSetMapIndexConstraint) solve(a *analysis, delta *nodeset) {
	for _, x := range delta.AppendTo(a.deltaSpace) {
		vObj := nodeid(x)
		tDyn, m, indirect := a.taggedValue(vObj)
		tMap, _ := tDyn.Underlying().(*types.Map)
		if tMap == nil {
			continue // not a map
		}
		if indirect {
			// TODO(adonovan): we'll need to implement this
			// when we start creating indirect tagged objects.
			panic("indirect tagged object")
		}

		keysize := a.sizeof(tMap.Key())

		// Extract key's payload to keytmp, then store to map key.
		keytmp := a.addNodes(tMap.Key(), "SetMapIndex.keytmp")
		a.typeAssert(tMap.Key(), keytmp, c.key, false)
		a.store(m, keytmp, 0, keysize)

		// Extract val's payload to vtmp, then store to map value.
		valtmp := a.addNodes(tMap.Elem(), "SetMapIndex.valtmp")
		a.typeAssert(tMap.Elem(), valtmp, c.val, false)
		a.store(m, valtmp, keysize, a.sizeof(tMap.Elem()))
	}
}

func ext۰reflect۰Value۰SetMapIndex(a *analysis, cgn *cgnode) {
	params := a.funcParams(cgn.obj)
	a.addConstraint(&rVSetMapIndexConstraint{
		cgn: cgn,
		v:   params,
		key: params + 1,
		val: params + 2,
	})
}

func ext۰reflect۰Value۰SetPointer(a *analysis, cgn *cgnode) {} // TODO(adonovan)

// ---------- func (Value).Slice(v Value, i, j int) Value ----------

// result = v.Slice(_, _)
type rVSliceConstraint struct {
	cgn    *cgnode
	v      nodeid // (ptr)
	result nodeid // (indirect)
}

func (c *rVSliceConstraint) ptr() nodeid { return c.v }
func (c *rVSliceConstraint) presolve(h *hvn) {
	h.markIndirect(onodeid(c.result), "rVSlice.result")
}
func (c *rVSliceConstraint) renumber(mapping []nodeid) {
	c.v = mapping[c.v]
	c.result = mapping[c.result]
}

func (c *rVSliceConstraint) String() string {
	return fmt.Sprintf("n%d = reflect n%d.Slice(_, _)", c.result, c.v)
}

func (c *rVSliceConstraint) solve(a *analysis, delta *nodeset) {
	changed := false
	for _, x := range delta.AppendTo(a.deltaSpace) {
		vObj := nodeid(x)
		tDyn, payload, indirect := a.taggedValue(vObj)
		if indirect {
			// TODO(adonovan): we'll need to implement this
			// when we start creating indirect tagged objects.
			panic("indirect tagged object")
		}

		var res nodeid
		switch t := tDyn.Underlying().(type) {
		case *types.Pointer:
			if tArr, ok := t.Elem().Underlying().(*types.Array); ok {
				// pointer to array
				res = a.makeTagged(types.NewSlice(tArr.Elem()), c.cgn, nil)
				if a.onlineCopy(res+1, payload) {
					a.addWork(res + 1)
				}
			}

		case *types.Array:
			// TODO(adonovan): implement addressable
			// arrays when we do indirect tagged objects.

		case *types.Slice:
			res = vObj

		case *types.Basic:
			if t == types.Typ[types.String] {
				res = vObj
			}
		}

		if res != 0 && a.addLabel(c.result, res) {
			changed = true
		}
	}
	if changed {
		a.addWork(c.result)
	}
}

func ext۰reflect۰Value۰Slice(a *analysis, cgn *cgnode) {
	a.addConstraint(&rVSliceConstraint{
		cgn:    cgn,
		v:      a.funcParams(cgn.obj),
		result: a.funcResults(cgn.obj),
	})
}

// -------------------- Standalone reflect functions --------------------

func ext۰reflect۰Append(a *analysis, cgn *cgnode)      {} // TODO(adonovan)
func ext۰reflect۰AppendSlice(a *analysis, cgn *cgnode) {} // TODO(adonovan)
func ext۰reflect۰Copy(a *analysis, cgn *cgnode)        {} // TODO(adonovan)

// ---------- func ChanOf(ChanDir, Type) Type ----------

// result = ChanOf(dir, t)
type reflectChanOfConstraint struct {
	cgn    *cgnode
	t      nodeid // (ptr)
	result nodeid // (indirect)
	dirs   []types.ChanDir
}

func (c *reflectChanOfConstraint) ptr() nodeid { return c.t }
func (c *reflectChanOfConstraint) presolve(h *hvn) {
	h.markIndirect(onodeid(c.result), "reflectChanOf.result")
}
func (c *reflectChanOfConstraint) renumber(mapping []nodeid) {
	c.t = mapping[c.t]
	c.result = mapping[c.result]
}

func (c *reflectChanOfConstraint) String() string {
	return fmt.Sprintf("n%d = reflect.ChanOf(n%d)", c.result, c.t)
}

func (c *reflectChanOfConstraint) solve(a *analysis, delta *nodeset) {
	changed := false
	for _, x := range delta.AppendTo(a.deltaSpace) {
		tObj := nodeid(x)
		T := a.rtypeTaggedValue(tObj)

		if typeTooHigh(T) {
			continue
		}

		for _, dir := range c.dirs {
			if a.addLabel(c.result, a.makeRtype(types.NewChan(dir, T))) {
				changed = true
			}
		}
	}
	if changed {
		a.addWork(c.result)
	}
}

// dirMap maps reflect.ChanDir to the set of channel types generated by ChanOf.
var dirMap = [...][]types.ChanDir{
	0:               {types.SendOnly, types.RecvOnly, types.SendRecv}, // unknown
	reflect.RecvDir: {types.RecvOnly},
	reflect.SendDir: {types.SendOnly},
	reflect.BothDir: {types.SendRecv},
}

func ext۰reflect۰ChanOf(a *analysis, cgn *cgnode) {
	// If we have access to the callsite,
	// and the channel argument is a constant (as is usual),
	// only generate the requested direction.
	var dir reflect.ChanDir // unknown
	if site := cgn.callersite; site != nil {
		if c, ok := site.instr.Common().Args[0].(*ssa.Const); ok {
			v, _ := exact.Int64Val(c.Value)
			if 0 <= v && v <= int64(reflect.BothDir) {
				dir = reflect.ChanDir(v)
			}
		}
	}

	params := a.funcParams(cgn.obj)
	a.addConstraint(&reflectChanOfConstraint{
		cgn:    cgn,
		t:      params + 1,
		result: a.funcResults(cgn.obj),
		dirs:   dirMap[dir],
	})
}

// ---------- func Indirect(v Value) Value ----------

// result = Indirect(v)
type reflectIndirectConstraint struct {
	cgn    *cgnode
	v      nodeid // (ptr)
	result nodeid // (indirect)
}

func (c *reflectIndirectConstraint) ptr() nodeid { return c.v }
func (c *reflectIndirectConstraint) presolve(h *hvn) {
	h.markIndirect(onodeid(c.result), "reflectIndirect.result")
}
func (c *reflectIndirectConstraint) renumber(mapping []nodeid) {
	c.v = mapping[c.v]
	c.result = mapping[c.result]
}

func (c *reflectIndirectConstraint) String() string {
	return fmt.Sprintf("n%d = reflect.Indirect(n%d)", c.result, c.v)
}

func (c *reflectIndirectConstraint) solve(a *analysis, delta *nodeset) {
	changed := false
	for _, x := range delta.AppendTo(a.deltaSpace) {
		vObj := nodeid(x)
		tDyn, _, _ := a.taggedValue(vObj)
		var res nodeid
		if tPtr, ok := tDyn.Underlying().(*types.Pointer); ok {
			// load the payload of the pointer's tagged object
			// into a new tagged object
			res = a.makeTagged(tPtr.Elem(), c.cgn, nil)
			a.load(res+1, vObj+1, 0, a.sizeof(tPtr.Elem()))
		} else {
			res = vObj
		}

		if a.addLabel(c.result, res) {
			changed = true
		}
	}
	if changed {
		a.addWork(c.result)
	}
}

func ext۰reflect۰Indirect(a *analysis, cgn *cgnode) {
	a.addConstraint(&reflectIndirectConstraint{
		cgn:    cgn,
		v:      a.funcParams(cgn.obj),
		result: a.funcResults(cgn.obj),
	})
}

// ---------- func MakeChan(Type) Value ----------

// result = MakeChan(typ)
type reflectMakeChanConstraint struct {
	cgn    *cgnode
	typ    nodeid // (ptr)
	result nodeid // (indirect)
}

func (c *reflectMakeChanConstraint) ptr() nodeid { return c.typ }
func (c *reflectMakeChanConstraint) presolve(h *hvn) {
	h.markIndirect(onodeid(c.result), "reflectMakeChan.result")
}
func (c *reflectMakeChanConstraint) renumber(mapping []nodeid) {
	c.typ = mapping[c.typ]
	c.result = mapping[c.result]
}

func (c *reflectMakeChanConstraint) String() string {
	return fmt.Sprintf("n%d = reflect.MakeChan(n%d)", c.result, c.typ)
}

func (c *reflectMakeChanConstraint) solve(a *analysis, delta *nodeset) {
	changed := false
	for _, x := range delta.AppendTo(a.deltaSpace) {
		typObj := nodeid(x)
		T := a.rtypeTaggedValue(typObj)
		tChan, ok := T.Underlying().(*types.Chan)
		if !ok || tChan.Dir() != types.SendRecv {
			continue // not a bidirectional channel type
		}

		obj := a.nextNode()
		a.addNodes(tChan.Elem(), "reflect.MakeChan.value")
		a.endObject(obj, c.cgn, nil)

		// put its address in a new T-tagged object
		id := a.makeTagged(T, c.cgn, nil)
		a.addLabel(id+1, obj)

		// flow the T-tagged object to the result
		if a.addLabel(c.result, id) {
			changed = true
		}
	}
	if changed {
		a.addWork(c.result)
	}
}

func ext۰reflect۰MakeChan(a *analysis, cgn *cgnode) {
	a.addConstraint(&reflectMakeChanConstraint{
		cgn:    cgn,
		typ:    a.funcParams(cgn.obj),
		result: a.funcResults(cgn.obj),
	})
}

func ext۰reflect۰MakeFunc(a *analysis, cgn *cgnode) {} // TODO(adonovan)

// ---------- func MakeMap(Type) Value ----------

// result = MakeMap(typ)
type reflectMakeMapConstraint struct {
	cgn    *cgnode
	typ    nodeid // (ptr)
	result nodeid // (indirect)
}

func (c *reflectMakeMapConstraint) ptr() nodeid { return c.typ }
func (c *reflectMakeMapConstraint) presolve(h *hvn) {
	h.markIndirect(onodeid(c.result), "reflectMakeMap.result")
}
func (c *reflectMakeMapConstraint) renumber(mapping []nodeid) {
	c.typ = mapping[c.typ]
	c.result = mapping[c.result]
}

func (c *reflectMakeMapConstraint) String() string {
	return fmt.Sprintf("n%d = reflect.MakeMap(n%d)", c.result, c.typ)
}

func (c *reflectMakeMapConstraint) solve(a *analysis, delta *nodeset) {
	changed := false
	for _, x := range delta.AppendTo(a.deltaSpace) {
		typObj := nodeid(x)
		T := a.rtypeTaggedValue(typObj)
		tMap, ok := T.Underlying().(*types.Map)
		if !ok {
			continue // not a map type
		}

		mapObj := a.nextNode()
		a.addNodes(tMap.Key(), "reflect.MakeMap.key")
		a.addNodes(tMap.Elem(), "reflect.MakeMap.value")
		a.endObject(mapObj, c.cgn, nil)

		// put its address in a new T-tagged object
		id := a.makeTagged(T, c.cgn, nil)
		a.addLabel(id+1, mapObj)

		// flow the T-tagged object to the result
		if a.addLabel(c.result, id) {
			changed = true
		}
	}
	if changed {
		a.addWork(c.result)
	}
}

func ext۰reflect۰MakeMap(a *analysis, cgn *cgnode) {
	a.addConstraint(&reflectMakeMapConstraint{
		cgn:    cgn,
		typ:    a.funcParams(cgn.obj),
		result: a.funcResults(cgn.obj),
	})
}

// ---------- func MakeSlice(Type) Value ----------

// result = MakeSlice(typ)
type reflectMakeSliceConstraint struct {
	cgn    *cgnode
	typ    nodeid // (ptr)
	result nodeid // (indirect)
}

func (c *reflectMakeSliceConstraint) ptr() nodeid { return c.typ }
func (c *reflectMakeSliceConstraint) presolve(h *hvn) {
	h.markIndirect(onodeid(c.result), "reflectMakeSlice.result")
}
func (c *reflectMakeSliceConstraint) renumber(mapping []nodeid) {
	c.typ = mapping[c.typ]
	c.result = mapping[c.result]
}

func (c *reflectMakeSliceConstraint) String() string {
	return fmt.Sprintf("n%d = reflect.MakeSlice(n%d)", c.result, c.typ)
}

func (c *reflectMakeSliceConstraint) solve(a *analysis, delta *nodeset) {
	changed := false
	for _, x := range delta.AppendTo(a.deltaSpace) {
		typObj := nodeid(x)
		T := a.rtypeTaggedValue(typObj)
		if _, ok := T.Underlying().(*types.Slice); !ok {
			continue // not a slice type
		}

		obj := a.nextNode()
		a.addNodes(sliceToArray(T), "reflect.MakeSlice")
		a.endObject(obj, c.cgn, nil)

		// put its address in a new T-tagged object
		id := a.makeTagged(T, c.cgn, nil)
		a.addLabel(id+1, obj)

		// flow the T-tagged object to the result
		if a.addLabel(c.result, id) {
			changed = true
		}
	}
	if changed {
		a.addWork(c.result)
	}
}

func ext۰reflect۰MakeSlice(a *analysis, cgn *cgnode) {
	a.addConstraint(&reflectMakeSliceConstraint{
		cgn:    cgn,
		typ:    a.funcParams(cgn.obj),
		result: a.funcResults(cgn.obj),
	})
}

func ext۰reflect۰MapOf(a *analysis, cgn *cgnode) {} // TODO(adonovan)

// ---------- func New(Type) Value ----------

// result = New(typ)
type reflectNewConstraint struct {
	cgn    *cgnode
	typ    nodeid // (ptr)
	result nodeid // (indirect)
}

func (c *reflectNewConstraint) ptr() nodeid { return c.typ }
func (c *reflectNewConstraint) presolve(h *hvn) {
	h.markIndirect(onodeid(c.result), "reflectNew.result")
}
func (c *reflectNewConstraint) renumber(mapping []nodeid) {
	c.typ = mapping[c.typ]
	c.result = mapping[c.result]
}

func (c *reflectNewConstraint) String() string {
	return fmt.Sprintf("n%d = reflect.New(n%d)", c.result, c.typ)
}

func (c *reflectNewConstraint) solve(a *analysis, delta *nodeset) {
	changed := false
	for _, x := range delta.AppendTo(a.deltaSpace) {
		typObj := nodeid(x)
		T := a.rtypeTaggedValue(typObj)

		// allocate new T object
		newObj := a.nextNode()
		a.addNodes(T, "reflect.New")
		a.endObject(newObj, c.cgn, nil)

		// put its address in a new *T-tagged object
		id := a.makeTagged(types.NewPointer(T), c.cgn, nil)
		a.addLabel(id+1, newObj)

		// flow the pointer to the result
		if a.addLabel(c.result, id) {
			changed = true
		}
	}
	if changed {
		a.addWork(c.result)
	}
}

func ext۰reflect۰New(a *analysis, cgn *cgnode) {
	a.addConstraint(&reflectNewConstraint{
		cgn:    cgn,
		typ:    a.funcParams(cgn.obj),
		result: a.funcResults(cgn.obj),
	})
}

func ext۰reflect۰NewAt(a *analysis, cgn *cgnode) {
	ext۰reflect۰New(a, cgn)

	// TODO(adonovan): also report dynamic calls to unsound intrinsics.
	if site := cgn.callersite; site != nil {
		a.warnf(site.pos(), "unsound: %s contains a reflect.NewAt() call", site.instr.Parent())
	}
}

// ---------- func PtrTo(Type) Type ----------

// result = PtrTo(t)
type reflectPtrToConstraint struct {
	cgn    *cgnode
	t      nodeid // (ptr)
	result nodeid // (indirect)
}

func (c *reflectPtrToConstraint) ptr() nodeid { return c.t }
func (c *reflectPtrToConstraint) presolve(h *hvn) {
	h.markIndirect(onodeid(c.result), "reflectPtrTo.result")
}
func (c *reflectPtrToConstraint) renumber(mapping []nodeid) {
	c.t = mapping[c.t]
	c.result = mapping[c.result]
}

func (c *reflectPtrToConstraint) String() string {
	return fmt.Sprintf("n%d = reflect.PtrTo(n%d)", c.result, c.t)
}

func (c *reflectPtrToConstraint) solve(a *analysis, delta *nodeset) {
	changed := false
	for _, x := range delta.AppendTo(a.deltaSpace) {
		tObj := nodeid(x)
		T := a.rtypeTaggedValue(tObj)

		if typeTooHigh(T) {
			continue
		}

		if a.addLabel(c.result, a.makeRtype(types.NewPointer(T))) {
			changed = true
		}
	}
	if changed {
		a.addWork(c.result)
	}
}

func ext۰reflect۰PtrTo(a *analysis, cgn *cgnode) {
	a.addConstraint(&reflectPtrToConstraint{
		cgn:    cgn,
		t:      a.funcParams(cgn.obj),
		result: a.funcResults(cgn.obj),
	})
}

func ext۰reflect۰Select(a *analysis, cgn *cgnode) {} // TODO(adonovan)

// ---------- func SliceOf(Type) Type ----------

// result = SliceOf(t)
type reflectSliceOfConstraint struct {
	cgn    *cgnode
	t      nodeid // (ptr)
	result nodeid // (indirect)
}

func (c *reflectSliceOfConstraint) ptr() nodeid { return c.t }
func (c *reflectSliceOfConstraint) presolve(h *hvn) {
	h.markIndirect(onodeid(c.result), "reflectSliceOf.result")
}
func (c *reflectSliceOfConstraint) renumber(mapping []nodeid) {
	c.t = mapping[c.t]
	c.result = mapping[c.result]
}

func (c *reflectSliceOfConstraint) String() string {
	return fmt.Sprintf("n%d = reflect.SliceOf(n%d)", c.result, c.t)
}

func (c *reflectSliceOfConstraint) solve(a *analysis, delta *nodeset) {
	changed := false
	for _, x := range delta.AppendTo(a.deltaSpace) {
		tObj := nodeid(x)
		T := a.rtypeTaggedValue(tObj)

		if typeTooHigh(T) {
			continue
		}

		if a.addLabel(c.result, a.makeRtype(types.NewSlice(T))) {
			changed = true
		}
	}
	if changed {
		a.addWork(c.result)
	}
}

func ext۰reflect۰SliceOf(a *analysis, cgn *cgnode) {
	a.addConstraint(&reflectSliceOfConstraint{
		cgn:    cgn,
		t:      a.funcParams(cgn.obj),
		result: a.funcResults(cgn.obj),
	})
}

// ---------- func TypeOf(v Value) Type ----------

// result = TypeOf(i)
type reflectTypeOfConstraint struct {
	cgn    *cgnode
	i      nodeid // (ptr)
	result nodeid // (indirect)
}

func (c *reflectTypeOfConstraint) ptr() nodeid { return c.i }
func (c *reflectTypeOfConstraint) presolve(h *hvn) {
	h.markIndirect(onodeid(c.result), "reflectTypeOf.result")
}
func (c *reflectTypeOfConstraint) renumber(mapping []nodeid) {
	c.i = mapping[c.i]
	c.result = mapping[c.result]
}

func (c *reflectTypeOfConstraint) String() string {
	return fmt.Sprintf("n%d = reflect.TypeOf(n%d)", c.result, c.i)
}

func (c *reflectTypeOfConstraint) solve(a *analysis, delta *nodeset) {
	changed := false
	for _, x := range delta.AppendTo(a.deltaSpace) {
		iObj := nodeid(x)
		tDyn, _, _ := a.taggedValue(iObj)
		if a.addLabel(c.result, a.makeRtype(tDyn)) {
			changed = true
		}
	}
	if changed {
		a.addWork(c.result)
	}
}

func ext۰reflect۰TypeOf(a *analysis, cgn *cgnode) {
	a.addConstraint(&reflectTypeOfConstraint{
		cgn:    cgn,
		i:      a.funcParams(cgn.obj),
		result: a.funcResults(cgn.obj),
	})
}

// ---------- func ValueOf(interface{}) Value ----------

func ext۰reflect۰ValueOf(a *analysis, cgn *cgnode) {
	// TODO(adonovan): when we start creating indirect tagged
	// objects, we'll need to handle them specially here since
	// they must never appear in the PTS of an interface{}.
	a.copy(a.funcResults(cgn.obj), a.funcParams(cgn.obj), 1)
}

// ---------- func Zero(Type) Value ----------

// result = Zero(typ)
type reflectZeroConstraint struct {
	cgn    *cgnode
	typ    nodeid // (ptr)
	result nodeid // (indirect)
}

func (c *reflectZeroConstraint) ptr() nodeid { return c.typ }
func (c *reflectZeroConstraint) presolve(h *hvn) {
	h.markIndirect(onodeid(c.result), "reflectZero.result")
}
func (c *reflectZeroConstraint) renumber(mapping []nodeid) {
	c.typ = mapping[c.typ]
	c.result = mapping[c.result]
}

func (c *reflectZeroConstraint) String() string {
	return fmt.Sprintf("n%d = reflect.Zero(n%d)", c.result, c.typ)
}

func (c *reflectZeroConstraint) solve(a *analysis, delta *nodeset) {
	changed := false
	for _, x := range delta.AppendTo(a.deltaSpace) {
		typObj := nodeid(x)
		T := a.rtypeTaggedValue(typObj)

		// TODO(adonovan): if T is an interface type, we need
		// to create an indirect tagged object containing
		// new(T).  To avoid updates of such shared values,
		// we'll need another flag on indirect tagged objects
		// that marks whether they are addressable or
		// readonly, just like the reflect package does.

		// memoize using a.reflectZeros[T]
		var id nodeid
		if z := a.reflectZeros.At(T); false && z != nil {
			id = z.(nodeid)
		} else {
			id = a.makeTagged(T, c.cgn, nil)
			a.reflectZeros.Set(T, id)
		}
		if a.addLabel(c.result, id) {
			changed = true
		}
	}
	if changed {
		a.addWork(c.result)
	}
}

func ext۰reflect۰Zero(a *analysis, cgn *cgnode) {
	a.addConstraint(&reflectZeroConstraint{
		cgn:    cgn,
		typ:    a.funcParams(cgn.obj),
		result: a.funcResults(cgn.obj),
	})
}

// -------------------- (*reflect.rtype) methods --------------------

// ---------- func (*rtype) Elem() Type ----------

// result = Elem(t)
type rtypeElemConstraint struct {
	cgn    *cgnode
	t      nodeid // (ptr)
	result nodeid // (indirect)
}

func (c *rtypeElemConstraint) ptr() nodeid { return c.t }
func (c *rtypeElemConstraint) presolve(h *hvn) {
	h.markIndirect(onodeid(c.result), "rtypeElem.result")
}
func (c *rtypeElemConstraint) renumber(mapping []nodeid) {
	c.t = mapping[c.t]
	c.result = mapping[c.result]
}

func (c *rtypeElemConstraint) String() string {
	return fmt.Sprintf("n%d = (*reflect.rtype).Elem(n%d)", c.result, c.t)
}

func (c *rtypeElemConstraint) solve(a *analysis, delta *nodeset) {
	// Implemented by *types.{Map,Chan,Array,Slice,Pointer}.
	type hasElem interface {
		Elem() types.Type
	}
	changed := false
	for _, x := range delta.AppendTo(a.deltaSpace) {
		tObj := nodeid(x)
		T := a.nodes[tObj].obj.data.(types.Type)
		if tHasElem, ok := T.Underlying().(hasElem); ok {
			if a.addLabel(c.result, a.makeRtype(tHasElem.Elem())) {
				changed = true
			}
		}
	}
	if changed {
		a.addWork(c.result)
	}
}

func ext۰reflect۰rtype۰Elem(a *analysis, cgn *cgnode) {
	a.addConstraint(&rtypeElemConstraint{
		cgn:    cgn,
		t:      a.funcParams(cgn.obj),
		result: a.funcResults(cgn.obj),
	})
}

// ---------- func (*rtype) Field(int) StructField ----------
// ---------- func (*rtype) FieldByName(string) (StructField, bool) ----------

// result = FieldByName(t, name)
// result = Field(t, _)
type rtypeFieldByNameConstraint struct {
	cgn    *cgnode
	name   string // name of field; "" for unknown
	t      nodeid // (ptr)
	result nodeid // (indirect)
}

func (c *rtypeFieldByNameConstraint) ptr() nodeid { return c.t }
func (c *rtypeFieldByNameConstraint) presolve(h *hvn) {
	h.markIndirect(onodeid(c.result+3), "rtypeFieldByName.result.Type")
}
func (c *rtypeFieldByNameConstraint) renumber(mapping []nodeid) {
	c.t = mapping[c.t]
	c.result = mapping[c.result]
}

func (c *rtypeFieldByNameConstraint) String() string {
	return fmt.Sprintf("n%d = (*reflect.rtype).FieldByName(n%d, %q)", c.result, c.t, c.name)
}

func (c *rtypeFieldByNameConstraint) solve(a *analysis, delta *nodeset) {
	// type StructField struct {
	// 0	__identity__
	// 1	Name      string
	// 2	PkgPath   string
	// 3	Type      Type
	// 4	Tag       StructTag
	// 5	Offset    uintptr
	// 6	Index     []int
	// 7	Anonymous bool
	// }

	for _, x := range delta.AppendTo(a.deltaSpace) {
		tObj := nodeid(x)
		T := a.nodes[tObj].obj.data.(types.Type)
		tStruct, ok := T.Underlying().(*types.Struct)
		if !ok {
			continue // not a struct type
		}

		n := tStruct.NumFields()
		for i := 0; i < n; i++ {
			f := tStruct.Field(i)
			if c.name == "" || c.name == f.Name() {

				// a.offsetOf(Type) is 3.
				if id := c.result + 3; a.addLabel(id, a.makeRtype(f.Type())) {
					a.addWork(id)
				}
				// TODO(adonovan): StructField.Index should be non-nil.
			}
		}
	}
}

func ext۰reflect۰rtype۰FieldByName(a *analysis, cgn *cgnode) {
	// If we have access to the callsite,
	// and the argument is a string constant,
	// return only that field.
	var name string
	if site := cgn.callersite; site != nil {
		if c, ok := site.instr.Common().Args[0].(*ssa.Const); ok {
			name = exact.StringVal(c.Value)
		}
	}

	a.addConstraint(&rtypeFieldByNameConstraint{
		cgn:    cgn,
		name:   name,
		t:      a.funcParams(cgn.obj),
		result: a.funcResults(cgn.obj),
	})
}

func ext۰reflect۰rtype۰Field(a *analysis, cgn *cgnode) {
	// No-one ever calls Field with a constant argument,
	// so we don't specialize that case.
	a.addConstraint(&rtypeFieldByNameConstraint{
		cgn:    cgn,
		t:      a.funcParams(cgn.obj),
		result: a.funcResults(cgn.obj),
	})
}

func ext۰reflect۰rtype۰FieldByIndex(a *analysis, cgn *cgnode)    {} // TODO(adonovan)
func ext۰reflect۰rtype۰FieldByNameFunc(a *analysis, cgn *cgnode) {} // TODO(adonovan)

// ---------- func (*rtype) In/Out(i int) Type ----------

// result = In/Out(t, i)
type rtypeInOutConstraint struct {
	cgn    *cgnode
	t      nodeid // (ptr)
	result nodeid // (indirect)
	out    bool
	i      int // -ve if not a constant
}

func (c *rtypeInOutConstraint) ptr() nodeid { return c.t }
func (c *rtypeInOutConstraint) presolve(h *hvn) {
	h.markIndirect(onodeid(c.result), "rtypeInOut.result")
}
func (c *rtypeInOutConstraint) renumber(mapping []nodeid) {
	c.t = mapping[c.t]
	c.result = mapping[c.result]
}

func (c *rtypeInOutConstraint) String() string {
	return fmt.Sprintf("n%d = (*reflect.rtype).InOut(n%d, %d)", c.result, c.t, c.i)
}

func (c *rtypeInOutConstraint) solve(a *analysis, delta *nodeset) {
	changed := false
	for _, x := range delta.AppendTo(a.deltaSpace) {
		tObj := nodeid(x)
		T := a.nodes[tObj].obj.data.(types.Type)
		sig, ok := T.Underlying().(*types.Signature)
		if !ok {
			continue // not a func type
		}

		tuple := sig.Params()
		if c.out {
			tuple = sig.Results()
		}
		for i, n := 0, tuple.Len(); i < n; i++ {
			if c.i < 0 || c.i == i {
				if a.addLabel(c.result, a.makeRtype(tuple.At(i).Type())) {
					changed = true
				}
			}
		}
	}
	if changed {
		a.addWork(c.result)
	}
}

func ext۰reflect۰rtype۰InOut(a *analysis, cgn *cgnode, out bool) {
	// If we have access to the callsite,
	// and the argument is an int constant,
	// return only that parameter.
	index := -1
	if site := cgn.callersite; site != nil {
		if c, ok := site.instr.Common().Args[0].(*ssa.Const); ok {
			v, _ := exact.Int64Val(c.Value)
			index = int(v)
		}
	}
	a.addConstraint(&rtypeInOutConstraint{
		cgn:    cgn,
		t:      a.funcParams(cgn.obj),
		result: a.funcResults(cgn.obj),
		out:    out,
		i:      index,
	})
}

func ext۰reflect۰rtype۰In(a *analysis, cgn *cgnode) {
	ext۰reflect۰rtype۰InOut(a, cgn, false)
}

func ext۰reflect۰rtype۰Out(a *analysis, cgn *cgnode) {
	ext۰reflect۰rtype۰InOut(a, cgn, true)
}

// ---------- func (*rtype) Key() Type ----------

// result = Key(t)
type rtypeKeyConstraint struct {
	cgn    *cgnode
	t      nodeid // (ptr)
	result nodeid // (indirect)
}

func (c *rtypeKeyConstraint) ptr() nodeid { return c.t }
func (c *rtypeKeyConstraint) presolve(h *hvn) {
	h.markIndirect(onodeid(c.result), "rtypeKey.result")
}
func (c *rtypeKeyConstraint) renumber(mapping []nodeid) {
	c.t = mapping[c.t]
	c.result = mapping[c.result]
}

func (c *rtypeKeyConstraint) String() string {
	return fmt.Sprintf("n%d = (*reflect.rtype).Key(n%d)", c.result, c.t)
}

func (c *rtypeKeyConstraint) solve(a *analysis, delta *nodeset) {
	changed := false
	for _, x := range delta.AppendTo(a.deltaSpace) {
		tObj := nodeid(x)
		T := a.nodes[tObj].obj.data.(types.Type)
		if tMap, ok := T.Underlying().(*types.Map); ok {
			if a.addLabel(c.result, a.makeRtype(tMap.Key())) {
				changed = true
			}
		}
	}
	if changed {
		a.addWork(c.result)
	}
}

func ext۰reflect۰rtype۰Key(a *analysis, cgn *cgnode) {
	a.addConstraint(&rtypeKeyConstraint{
		cgn:    cgn,
		t:      a.funcParams(cgn.obj),
		result: a.funcResults(cgn.obj),
	})
}

// ---------- func (*rtype) Method(int) (Method, bool) ----------
// ---------- func (*rtype) MethodByName(string) (Method, bool) ----------

// result = MethodByName(t, name)
// result = Method(t, _)
type rtypeMethodByNameConstraint struct {
	cgn    *cgnode
	name   string // name of method; "" for unknown
	t      nodeid // (ptr)
	result nodeid // (indirect)
}

func (c *rtypeMethodByNameConstraint) ptr() nodeid { return c.t }
func (c *rtypeMethodByNameConstraint) presolve(h *hvn) {
	h.markIndirect(onodeid(c.result+3), "rtypeMethodByName.result.Type")
	h.markIndirect(onodeid(c.result+4), "rtypeMethodByName.result.Func")
}
func (c *rtypeMethodByNameConstraint) renumber(mapping []nodeid) {
	c.t = mapping[c.t]
	c.result = mapping[c.result]
}

func (c *rtypeMethodByNameConstraint) String() string {
	return fmt.Sprintf("n%d = (*reflect.rtype).MethodByName(n%d, %q)", c.result, c.t, c.name)
}

// changeRecv returns sig with Recv prepended to Params().
func changeRecv(sig *types.Signature) *types.Signature {
	params := sig.Params()
	n := params.Len()
	p2 := make([]*types.Var, n+1)
	p2[0] = sig.Recv()
	for i := 0; i < n; i++ {
		p2[i+1] = params.At(i)
	}
	return types.NewSignature(nil, nil, types.NewTuple(p2...), sig.Results(), sig.Variadic())
}

func (c *rtypeMethodByNameConstraint) solve(a *analysis, delta *nodeset) {
	for _, x := range delta.AppendTo(a.deltaSpace) {
		tObj := nodeid(x)
		T := a.nodes[tObj].obj.data.(types.Type)

		isIface := isInterface(T)

		// We don't use Lookup(c.name) when c.name != "" to avoid
		// ambiguity: >1 unexported methods could match.
		mset := a.prog.MethodSets.MethodSet(T)
		for i, n := 0, mset.Len(); i < n; i++ {
			sel := mset.At(i)
			if c.name == "" || c.name == sel.Obj().Name() {
				// type Method struct {
				// 0     __identity__
				// 1	Name    string
				// 2	PkgPath string
				// 3	Type    Type
				// 4	Func    Value
				// 5	Index   int
				// }

				var sig *types.Signature
				var fn *ssa.Function
				if isIface {
					sig = sel.Type().(*types.Signature)
				} else {
					fn = a.prog.Method(sel)
					// move receiver to params[0]
					sig = changeRecv(fn.Signature)
				}

				// a.offsetOf(Type) is 3.
				if id := c.result + 3; a.addLabel(id, a.makeRtype(sig)) {
					a.addWork(id)
				}
				if fn != nil {
					// a.offsetOf(Func) is 4.
					if id := c.result + 4; a.addLabel(id, a.objectNode(nil, fn)) {
						a.addWork(id)
					}
				}
			}
		}
	}
}

func ext۰reflect۰rtype۰MethodByName(a *analysis, cgn *cgnode) {
	// If we have access to the callsite,
	// and the argument is a string constant,
	// return only that method.
	var name string
	if site := cgn.callersite; site != nil {
		if c, ok := site.instr.Common().Args[0].(*ssa.Const); ok {
			name = exact.StringVal(c.Value)
		}
	}

	a.addConstraint(&rtypeMethodByNameConstraint{
		cgn:    cgn,
		name:   name,
		t:      a.funcParams(cgn.obj),
		result: a.funcResults(cgn.obj),
	})
}

func ext۰reflect۰rtype۰Method(a *analysis, cgn *cgnode) {
	// No-one ever calls Method with a constant argument,
	// so we don't specialize that case.
	a.addConstraint(&rtypeMethodByNameConstraint{
		cgn:    cgn,
		t:      a.funcParams(cgn.obj),
		result: a.funcResults(cgn.obj),
	})
}

// typeHeight returns the "height" of the type, which is roughly
// speaking the number of chan, map, pointer and slice type constructors
// at the root of T; these are the four type kinds that can be created
// via reflection.  Chan and map constructors are counted as double the
// height of slice and pointer constructors since they are less often
// deeply nested.
//
// The solver rules for type constructors must somehow bound the set of
// types they create to ensure termination of the algorithm in cases
// where the output of a type constructor flows to its input, e.g.
//
// 	func f(t reflect.Type) {
// 		f(reflect.PtrTo(t))
// 	}
//
// It does this by limiting the type height to k, but this still leaves
// a potentially exponential (4^k) number of of types that may be
// enumerated in pathological cases.
//
func typeHeight(T types.Type) int {
	switch T := T.(type) {
	case *types.Chan:
		return 2 + typeHeight(T.Elem())
	case *types.Map:
		k := typeHeight(T.Key())
		v := typeHeight(T.Elem())
		if v > k {
			k = v // max(k, v)
		}
		return 2 + k
	case *types.Slice:
		return 1 + typeHeight(T.Elem())
	case *types.Pointer:
		return 1 + typeHeight(T.Elem())
	}
	return 0
}

func typeTooHigh(T types.Type) bool {
	return typeHeight(T) > 3
}
