src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

builder.go (94823B)


      1 // Copyright 2013 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package ssa
      6 
      7 // This file defines the builder, which builds SSA-form IR for function bodies.
      8 //
      9 // SSA construction has two phases, "create" and "build". First, one
     10 // or more packages are created in any order by a sequence of calls to
     11 // CreatePackage, either from syntax or from mere type information.
     12 // Each created package has a complete set of Members (const, var,
     13 // type, func) that can be accessed through methods like
     14 // Program.FuncValue.
     15 //
     16 // It is not necessary to call CreatePackage for all dependencies of
     17 // each syntax package, only for its direct imports. (In future
     18 // perhaps even this restriction may be lifted.)
     19 //
     20 // Second, packages created from syntax are built, by one or more
     21 // calls to Package.Build, which may be concurrent; or by a call to
     22 // Program.Build, which builds all packages in parallel. Building
     23 // traverses the type-annotated syntax tree of each function body and
     24 // creates SSA-form IR, a control-flow graph of instructions,
     25 // populating fields such as Function.Body, .Params, and others.
     26 //
     27 // Building may create additional methods, including:
     28 // - wrapper methods (e.g. for embedding, or implicit &recv)
     29 // - bound method closures (e.g. for use(recv.f))
     30 // - thunks (e.g. for use(I.f) or use(T.f))
     31 // - generic instances (e.g. to produce f[int] from f[any]).
     32 // As these methods are created, they are added to the build queue,
     33 // and then processed in turn, until a fixed point is reached,
     34 // Since these methods might belong to packages that were not
     35 // created (by a call to CreatePackage), their Pkg field is unset.
     36 //
     37 // Instances of generic functions may be either instantiated (f[int]
     38 // is a copy of f[T] with substitutions) or wrapped (f[int] delegates
     39 // to f[T]), depending on the availability of generic syntax and the
     40 // InstantiateGenerics mode flag.
     41 //
     42 // Each package has an initializer function named "init" that calls
     43 // the initializer functions of each direct import, computes and
     44 // assigns the initial value of each global variable, and calls each
     45 // source-level function named "init". (These generate SSA functions
     46 // named "init#1", "init#2", etc.)
     47 //
     48 // Runtime types
     49 //
     50 // Each MakeInterface operation is a conversion from a non-interface
     51 // type to an interface type. The semantics of this operation requires
     52 // a runtime type descriptor, which is the type portion of an
     53 // interface, and the value abstracted by reflect.Type.
     54 //
     55 // The program accumulates all non-parameterized types that are
     56 // encountered as MakeInterface operands, along with all types that
     57 // may be derived from them using reflection. This set is available as
     58 // Program.RuntimeTypes, and the methods of these types may be
     59 // reachable via interface calls or reflection even if they are never
     60 // referenced from the SSA IR. (In practice, algorithms such as RTA
     61 // that compute reachability from package main perform their own
     62 // tracking of runtime types at a finer grain, so this feature is not
     63 // very useful.)
     64 //
     65 // Function literals
     66 //
     67 // Anonymous functions must be built as soon as they are encountered,
     68 // as it may affect locals of the enclosing function, but they are not
     69 // marked 'built' until the end of the outermost enclosing function.
     70 // (Among other things, this causes them to be logged in top-down order.)
     71 //
     72 // The Function.build fields determines the algorithm for building the
     73 // function body. It is cleared to mark that building is complete.
     74 
     75 import (
     76 	"fmt"
     77 	"go/ast"
     78 	"go/constant"
     79 	"go/token"
     80 	"go/types"
     81 	"os"
     82 	"runtime"
     83 	"sync"
     84 
     85 	"slices"
     86 
     87 	"golang.org/x/tools/internal/typeparams"
     88 	"golang.org/x/tools/internal/typesinternal"
     89 	"golang.org/x/tools/internal/versions"
     90 )
     91 
     92 type opaqueType struct{ name string }
     93 
     94 func (t *opaqueType) String() string         { return t.name }
     95 func (t *opaqueType) Underlying() types.Type { return t }
     96 
     97 var (
     98 	varOk    = newVar("ok", tBool)
     99 	varIndex = newVar("index", tInt)
    100 
    101 	// Type constants.
    102 	tBool       = types.Typ[types.Bool]
    103 	tByte       = types.Typ[types.Byte]
    104 	tRune       = types.Universe.Lookup("rune").Type() // prints as "rune" (Typ[Rune] is same as Int32)
    105 	tInt        = types.Typ[types.Int]
    106 	tInvalid    = types.Typ[types.Invalid]
    107 	tString     = types.Typ[types.String]
    108 	tUntypedNil = types.Typ[types.UntypedNil]
    109 
    110 	tRangeIter  = &opaqueType{"iter"}                         // the type of all "range" iterators
    111 	tDeferStack = types.NewPointer(&opaqueType{"deferStack"}) // the type of a "deferStack" from ssa:deferstack()
    112 	tEface      = types.NewInterfaceType(nil, nil).Complete()
    113 
    114 	// SSA Value constants.
    115 	vZero     = intConst(0)
    116 	vOne      = intConst(1)
    117 	vTrue     = NewConst(constant.MakeBool(true), tBool)
    118 	vFalse    = NewConst(constant.MakeBool(false), tBool)
    119 	vNoReturn = NewConst(constant.MakeString("noreturn"), tString)
    120 
    121 	jReady = intConst(0)  // range-over-func jump is READY
    122 	jBusy  = intConst(-1) // range-over-func jump is BUSY
    123 	jDone  = intConst(-2) // range-over-func jump is DONE
    124 
    125 	// The ssa:deferstack intrinsic returns the current function's defer stack.
    126 	vDeferStack = &Builtin{
    127 		name: "ssa:deferstack",
    128 		sig:  types.NewSignatureType(nil, nil, nil, nil, typesinternal.TupleOf(tDeferStack), false),
    129 	}
    130 )
    131 
    132 // builder holds state associated with the package currently being built.
    133 // Its methods contain all the logic for AST-to-SSA conversion.
    134 //
    135 // All Functions belong to the same Program.
    136 //
    137 // builders are not thread-safe.
    138 type builder struct {
    139 	fns []*Function // Functions that have finished their CREATE phases.
    140 
    141 	finished int // finished is the length of the prefix of fns containing built functions.
    142 
    143 	// The task of building shared functions within the builder.
    144 	// Shared functions are ones the builder may either create or lookup.
    145 	// These may be built by other builders in parallel.
    146 	// The task is done when the builder has finished iterating, and it
    147 	// waits for all shared functions to finish building.
    148 	// nil implies there are no hared functions to wait on.
    149 	buildshared *task
    150 }
    151 
    152 // shared is done when the builder has built all of the
    153 // enqueued functions to a fixed-point.
    154 func (b *builder) shared() *task {
    155 	if b.buildshared == nil { // lazily-initialize
    156 		b.buildshared = &task{done: make(chan unit)}
    157 	}
    158 	return b.buildshared
    159 }
    160 
    161 // enqueue fn to be built by the builder.
    162 func (b *builder) enqueue(fn *Function) {
    163 	b.fns = append(b.fns, fn)
    164 }
    165 
    166 // waitForSharedFunction indicates that the builder should wait until
    167 // the potentially shared function fn has finished building.
    168 //
    169 // This should include any functions that may be built by other
    170 // builders.
    171 func (b *builder) waitForSharedFunction(fn *Function) {
    172 	if fn.buildshared != nil { // maybe need to wait?
    173 		s := b.shared()
    174 		s.addEdge(fn.buildshared)
    175 	}
    176 }
    177 
    178 // cond emits to fn code to evaluate boolean condition e and jump
    179 // to t or f depending on its value, performing various simplifications.
    180 //
    181 // Postcondition: fn.currentBlock is nil.
    182 func (b *builder) cond(fn *Function, e ast.Expr, t, f *BasicBlock) {
    183 	switch e := e.(type) {
    184 	case *ast.ParenExpr:
    185 		b.cond(fn, e.X, t, f)
    186 		return
    187 
    188 	case *ast.BinaryExpr:
    189 		switch e.Op {
    190 		case token.LAND:
    191 			ltrue := fn.newBasicBlock("cond.true")
    192 			b.cond(fn, e.X, ltrue, f)
    193 			fn.currentBlock = ltrue
    194 			b.cond(fn, e.Y, t, f)
    195 			return
    196 
    197 		case token.LOR:
    198 			lfalse := fn.newBasicBlock("cond.false")
    199 			b.cond(fn, e.X, t, lfalse)
    200 			fn.currentBlock = lfalse
    201 			b.cond(fn, e.Y, t, f)
    202 			return
    203 		}
    204 
    205 	case *ast.UnaryExpr:
    206 		if e.Op == token.NOT {
    207 			b.cond(fn, e.X, f, t)
    208 			return
    209 		}
    210 	}
    211 
    212 	// A traditional compiler would simplify "if false" (etc) here
    213 	// but we do not, for better fidelity to the source code.
    214 	//
    215 	// The value of a constant condition may be platform-specific,
    216 	// and may cause blocks that are reachable in some configuration
    217 	// to be hidden from subsequent analyses such as bug-finding tools.
    218 	emitIf(fn, b.expr(fn, e), t, f)
    219 }
    220 
    221 // logicalBinop emits code to fn to evaluate e, a &&- or
    222 // ||-expression whose reified boolean value is wanted.
    223 // The value is returned.
    224 func (b *builder) logicalBinop(fn *Function, e *ast.BinaryExpr) Value {
    225 	rhs := fn.newBasicBlock("binop.rhs")
    226 	done := fn.newBasicBlock("binop.done")
    227 
    228 	// T(e) = T(e.X) = T(e.Y) after untyped constants have been
    229 	// eliminated.
    230 	// TODO(adonovan): not true; MyBool==MyBool yields UntypedBool.
    231 	t := fn.typeOf(e)
    232 
    233 	var short Value // value of the short-circuit path
    234 	switch e.Op {
    235 	case token.LAND:
    236 		b.cond(fn, e.X, rhs, done)
    237 		short = NewConst(constant.MakeBool(false), t)
    238 
    239 	case token.LOR:
    240 		b.cond(fn, e.X, done, rhs)
    241 		short = NewConst(constant.MakeBool(true), t)
    242 	}
    243 
    244 	// Is rhs unreachable?
    245 	if rhs.Preds == nil {
    246 		// Simplify false&&y to false, true||y to true.
    247 		fn.currentBlock = done
    248 		return short
    249 	}
    250 
    251 	// Is done unreachable?
    252 	if done.Preds == nil {
    253 		// Simplify true&&y (or false||y) to y.
    254 		fn.currentBlock = rhs
    255 		return b.expr(fn, e.Y)
    256 	}
    257 
    258 	// All edges from e.X to done carry the short-circuit value.
    259 	var edges []Value
    260 	for range done.Preds {
    261 		edges = append(edges, short)
    262 	}
    263 
    264 	// The edge from e.Y to done carries the value of e.Y.
    265 	fn.currentBlock = rhs
    266 	edges = append(edges, b.expr(fn, e.Y))
    267 	emitJump(fn, done)
    268 	fn.currentBlock = done
    269 
    270 	phi := &Phi{Edges: edges, Comment: e.Op.String()}
    271 	phi.pos = e.OpPos
    272 	phi.typ = t
    273 	return done.emit(phi)
    274 }
    275 
    276 // exprN lowers a multi-result expression e to SSA form, emitting code
    277 // to fn and returning a single Value whose type is a *types.Tuple.
    278 // The caller must access the components via Extract.
    279 //
    280 // Multi-result expressions include CallExprs in a multi-value
    281 // assignment or return statement, and "value,ok" uses of
    282 // TypeAssertExpr, IndexExpr (when X is a map), and UnaryExpr (when Op
    283 // is token.ARROW).
    284 func (b *builder) exprN(fn *Function, e ast.Expr) Value {
    285 	typ := fn.typeOf(e).(*types.Tuple)
    286 	switch e := e.(type) {
    287 	case *ast.ParenExpr:
    288 		return b.exprN(fn, e.X)
    289 
    290 	case *ast.CallExpr:
    291 		// Currently, no built-in function nor type conversion
    292 		// has multiple results, so we can avoid some of the
    293 		// cases for single-valued CallExpr.
    294 		var c Call
    295 		b.setCall(fn, e, &c.Call)
    296 		c.typ = typ
    297 		return emitCall(fn, &c)
    298 
    299 	case *ast.IndexExpr:
    300 		mapt := typeparams.CoreType(fn.typeOf(e.X)).(*types.Map) // ,ok must be a map.
    301 		lookup := &Lookup{
    302 			X:       b.expr(fn, e.X),
    303 			Index:   emitConv(fn, b.expr(fn, e.Index), mapt.Key()),
    304 			CommaOk: true,
    305 		}
    306 		lookup.setType(typ)
    307 		lookup.setPos(e.Lbrack)
    308 		return fn.emit(lookup)
    309 
    310 	case *ast.TypeAssertExpr:
    311 		return emitTypeTest(fn, b.expr(fn, e.X), typ.At(0).Type(), e.Lparen)
    312 
    313 	case *ast.UnaryExpr: // must be receive <-
    314 		unop := &UnOp{
    315 			Op:      token.ARROW,
    316 			X:       b.expr(fn, e.X),
    317 			CommaOk: true,
    318 		}
    319 		unop.setType(typ)
    320 		unop.setPos(e.OpPos)
    321 		return fn.emit(unop)
    322 	}
    323 	panic(fmt.Sprintf("exprN(%T) in %s", e, fn))
    324 }
    325 
    326 // builtin emits to fn SSA instructions to implement a call to the
    327 // built-in function obj with the specified arguments
    328 // and return type.  It returns the value defined by the result.
    329 //
    330 // The result is nil if no special handling was required; in this case
    331 // the caller should treat this like an ordinary library function
    332 // call.
    333 func (b *builder) builtin(fn *Function, obj *types.Builtin, args []ast.Expr, typ types.Type, pos token.Pos) Value {
    334 	typ = fn.typ(typ)
    335 	switch obj.Name() {
    336 	case "make":
    337 		switch ct := typeparams.CoreType(typ).(type) {
    338 		case *types.Slice:
    339 			n := b.expr(fn, args[1])
    340 			m := n
    341 			if len(args) == 3 {
    342 				m = b.expr(fn, args[2])
    343 			}
    344 			if m, ok := m.(*Const); ok {
    345 				// treat make([]T, n, m) as new([m]T)[:n]
    346 				cap := m.Int64()
    347 				at := types.NewArray(ct.Elem(), cap)
    348 				v := &Slice{
    349 					X:    emitNew(fn, at, pos, "makeslice"),
    350 					High: n,
    351 				}
    352 				v.setPos(pos)
    353 				v.setType(typ)
    354 				return fn.emit(v)
    355 			}
    356 			v := &MakeSlice{
    357 				Len: n,
    358 				Cap: m,
    359 			}
    360 			v.setPos(pos)
    361 			v.setType(typ)
    362 			return fn.emit(v)
    363 
    364 		case *types.Map:
    365 			var res Value
    366 			if len(args) == 2 {
    367 				res = b.expr(fn, args[1])
    368 			}
    369 			v := &MakeMap{Reserve: res}
    370 			v.setPos(pos)
    371 			v.setType(typ)
    372 			return fn.emit(v)
    373 
    374 		case *types.Chan:
    375 			var sz Value = vZero
    376 			if len(args) == 2 {
    377 				sz = b.expr(fn, args[1])
    378 			}
    379 			v := &MakeChan{Size: sz}
    380 			v.setPos(pos)
    381 			v.setType(typ)
    382 			return fn.emit(v)
    383 		}
    384 
    385 	case "new":
    386 		alloc := emitNew(fn, typeparams.MustDeref(typ), pos, "new")
    387 		if !fn.info.Types[args[0]].IsType() {
    388 			// new(expr), requires go1.26
    389 			v := b.expr(fn, args[0])
    390 			emitStore(fn, alloc, v, pos)
    391 		}
    392 		return alloc
    393 
    394 	case "len", "cap":
    395 		// Special case: len or cap of an array or *array is
    396 		// based on the type, not the value which may be nil.
    397 		// We must still evaluate the value, though.  (If it
    398 		// was side-effect free, the whole call would have
    399 		// been constant-folded.)
    400 		t := typeparams.Deref(fn.typeOf(args[0]))
    401 		if at, ok := typeparams.CoreType(t).(*types.Array); ok {
    402 			b.expr(fn, args[0]) // for effects only
    403 			return intConst(at.Len())
    404 		}
    405 		// Otherwise treat as normal.
    406 
    407 	case "panic":
    408 		fn.emit(&Panic{
    409 			X:   emitConv(fn, b.expr(fn, args[0]), tEface),
    410 			pos: pos,
    411 		})
    412 		fn.currentBlock = fn.newBasicBlock("unreachable")
    413 		return vTrue // any non-nil Value will do
    414 	}
    415 	return nil // treat all others as a regular function call
    416 }
    417 
    418 // addr lowers a single-result addressable expression e to SSA form,
    419 // emitting code to fn and returning the location (an lvalue) defined
    420 // by the expression.
    421 //
    422 // If escaping is true, addr marks the base variable of the
    423 // addressable expression e as being a potentially escaping pointer
    424 // value.  For example, in this code:
    425 //
    426 //	a := A{
    427 //	  b: [1]B{B{c: 1}}
    428 //	}
    429 //	return &a.b[0].c
    430 //
    431 // the application of & causes a.b[0].c to have its address taken,
    432 // which means that ultimately the local variable a must be
    433 // heap-allocated.  This is a simple but very conservative escape
    434 // analysis.
    435 //
    436 // Operations forming potentially escaping pointers include:
    437 // - &x, including when implicit in method call or composite literals.
    438 // - a[:] iff a is an array (not *array)
    439 // - references to variables in lexically enclosing functions.
    440 func (b *builder) addr(fn *Function, e ast.Expr, escaping bool) lvalue {
    441 	switch e := e.(type) {
    442 	case *ast.Ident:
    443 		if isBlankIdent(e) {
    444 			return blank{}
    445 		}
    446 		obj := fn.objectOf(e).(*types.Var)
    447 		var v Value
    448 		if g := fn.Prog.packageLevelMember(obj); g != nil {
    449 			v = g.(*Global) // var (address)
    450 		} else {
    451 			v = fn.lookup(obj, escaping)
    452 		}
    453 		return &address{addr: v, pos: e.Pos(), expr: e}
    454 
    455 	case *ast.CompositeLit:
    456 		typ := typeparams.Deref(fn.typeOf(e))
    457 		var v *Alloc
    458 		if escaping {
    459 			v = emitNew(fn, typ, e.Lbrace, "complit")
    460 		} else {
    461 			v = emitLocal(fn, typ, e.Lbrace, "complit")
    462 		}
    463 		var sb storebuf
    464 		b.compLit(fn, v, e, true, &sb)
    465 		sb.emit(fn)
    466 		return &address{addr: v, pos: e.Lbrace, expr: e}
    467 
    468 	case *ast.ParenExpr:
    469 		return b.addr(fn, e.X, escaping)
    470 
    471 	case *ast.SelectorExpr:
    472 		sel := fn.selection(e)
    473 		if sel == nil {
    474 			// qualified identifier
    475 			return b.addr(fn, e.Sel, escaping)
    476 		}
    477 		if sel.kind != types.FieldVal {
    478 			panic(sel)
    479 		}
    480 		wantAddr := true
    481 		v := b.receiver(fn, e.X, wantAddr, escaping, sel)
    482 		index := sel.index[len(sel.index)-1]
    483 		fld := fieldOf(typeparams.MustDeref(v.Type()), index) // v is an addr.
    484 
    485 		// Due to the two phases of resolving AssignStmt, a panic from x.f = p()
    486 		// when x is nil is required to come after the side-effects of
    487 		// evaluating x and p().
    488 		emit := func(fn *Function) Value {
    489 			return emitFieldSelection(fn, v, index, true, e.Sel)
    490 		}
    491 		return &lazyAddress{addr: emit, t: fld.Type(), pos: e.Sel.Pos(), expr: e.Sel}
    492 
    493 	case *ast.IndexExpr:
    494 		xt := fn.typeOf(e.X)
    495 		elem, mode := indexType(xt)
    496 		var x Value
    497 		var et types.Type
    498 		switch mode {
    499 		case ixArrVar: // array, array|slice, array|*array, or array|*array|slice.
    500 			x = b.addr(fn, e.X, escaping).address(fn)
    501 			et = types.NewPointer(elem)
    502 		case ixVar: // *array, slice, *array|slice
    503 			x = b.expr(fn, e.X)
    504 			et = types.NewPointer(elem)
    505 		case ixMap:
    506 			mt := typeparams.CoreType(xt).(*types.Map)
    507 			return &element{
    508 				m:   b.expr(fn, e.X),
    509 				k:   emitConv(fn, b.expr(fn, e.Index), mt.Key()),
    510 				t:   mt.Elem(),
    511 				pos: e.Lbrack,
    512 			}
    513 		default:
    514 			panic("unexpected container type in IndexExpr: " + xt.String())
    515 		}
    516 		index := b.expr(fn, e.Index)
    517 		if isUntyped(index.Type()) {
    518 			index = emitConv(fn, index, tInt)
    519 		}
    520 		// Due to the two phases of resolving AssignStmt, a panic from x[i] = p()
    521 		// when x is nil or i is out-of-bounds is required to come after the
    522 		// side-effects of evaluating x, i and p().
    523 		emit := func(fn *Function) Value {
    524 			v := &IndexAddr{
    525 				X:     x,
    526 				Index: index,
    527 			}
    528 			v.setPos(e.Lbrack)
    529 			v.setType(et)
    530 			return fn.emit(v)
    531 		}
    532 		return &lazyAddress{addr: emit, t: typeparams.MustDeref(et), pos: e.Lbrack, expr: e}
    533 
    534 	case *ast.StarExpr:
    535 		return &address{addr: b.expr(fn, e.X), pos: e.Star, expr: e}
    536 	}
    537 
    538 	panic(fmt.Sprintf("unexpected address expression: %T", e))
    539 }
    540 
    541 type store struct {
    542 	lhs lvalue
    543 	rhs Value
    544 }
    545 
    546 type storebuf struct{ stores []store }
    547 
    548 func (sb *storebuf) store(lhs lvalue, rhs Value) {
    549 	sb.stores = append(sb.stores, store{lhs, rhs})
    550 }
    551 
    552 func (sb *storebuf) emit(fn *Function) {
    553 	for _, s := range sb.stores {
    554 		s.lhs.store(fn, s.rhs)
    555 	}
    556 }
    557 
    558 // assign emits to fn code to initialize the lvalue loc with the value
    559 // of expression e.  If isZero is true, assign assumes that loc holds
    560 // the zero value for its type.
    561 //
    562 // This is equivalent to loc.store(fn, b.expr(fn, e)), but may generate
    563 // better code in some cases, e.g., for composite literals in an
    564 // addressable location.
    565 //
    566 // If sb is not nil, assign generates code to evaluate expression e, but
    567 // not to update loc.  Instead, the necessary stores are appended to the
    568 // storebuf sb so that they can be executed later.  This allows correct
    569 // in-place update of existing variables when the RHS is a composite
    570 // literal that may reference parts of the LHS.
    571 func (b *builder) assign(fn *Function, loc lvalue, e ast.Expr, isZero bool, sb *storebuf) {
    572 	// Can we initialize it in place?
    573 	if e, ok := ast.Unparen(e).(*ast.CompositeLit); ok {
    574 		// A CompositeLit never evaluates to a pointer,
    575 		// so if the type of the location is a pointer,
    576 		// an &-operation is implied.
    577 		if !is[blank](loc) && isPointerCore(loc.typ()) { // avoid calling blank.typ()
    578 			ptr := b.addr(fn, e, true).address(fn)
    579 			// copy address
    580 			if sb != nil {
    581 				sb.store(loc, ptr)
    582 			} else {
    583 				loc.store(fn, ptr)
    584 			}
    585 			return
    586 		}
    587 	}
    588 
    589 	// simple case: just copy
    590 	rhs := b.expr(fn, e)
    591 	if sb != nil {
    592 		sb.store(loc, rhs)
    593 	} else {
    594 		loc.store(fn, rhs)
    595 	}
    596 }
    597 
    598 // expr lowers a single-result expression e to SSA form, emitting code
    599 // to fn and returning the Value defined by the expression.
    600 func (b *builder) expr(fn *Function, e ast.Expr) Value {
    601 	e = ast.Unparen(e)
    602 
    603 	tv := fn.info.Types[e]
    604 
    605 	// Is expression a constant?
    606 	if tv.Value != nil {
    607 		return NewConst(tv.Value, fn.typ(tv.Type))
    608 	}
    609 
    610 	var v Value
    611 	if tv.Addressable() {
    612 		// Prefer pointer arithmetic ({Index,Field}Addr) followed
    613 		// by Load over subelement extraction (e.g. Index, Field),
    614 		// to avoid large copies.
    615 		v = b.addr(fn, e, false).load(fn)
    616 	} else {
    617 		v = b.expr0(fn, e, tv)
    618 	}
    619 	if fn.debugInfo() {
    620 		emitDebugRef(fn, e, v, false)
    621 	}
    622 	return v
    623 }
    624 
    625 func (b *builder) expr0(fn *Function, e ast.Expr, tv types.TypeAndValue) Value {
    626 	switch e := e.(type) {
    627 	case *ast.BasicLit:
    628 		panic("non-constant BasicLit") // unreachable
    629 
    630 	case *ast.FuncLit:
    631 		/* function literal */
    632 		anon := &Function{
    633 			name:           fmt.Sprintf("%s$%d", fn.Name(), 1+len(fn.AnonFuncs)),
    634 			Signature:      fn.typeOf(e.Type).(*types.Signature),
    635 			pos:            e.Type.Func,
    636 			parent:         fn,
    637 			anonIdx:        int32(len(fn.AnonFuncs)),
    638 			Pkg:            fn.Pkg,
    639 			Prog:           fn.Prog,
    640 			syntax:         e,
    641 			info:           fn.info,
    642 			goversion:      fn.goversion,
    643 			build:          (*builder).buildFromSyntax,
    644 			topLevelOrigin: nil,           // use anonIdx to lookup an anon instance's origin.
    645 			typeparams:     fn.typeparams, // share the parent's type parameters.
    646 			typeargs:       fn.typeargs,   // share the parent's type arguments.
    647 			subst:          fn.subst,      // share the parent's type substitutions.
    648 			uniq:           fn.uniq,       // start from parent's unique values
    649 		}
    650 		fn.AnonFuncs = append(fn.AnonFuncs, anon)
    651 		// Build anon immediately, as it may cause fn's locals to escape.
    652 		// (It is not marked 'built' until the end of the enclosing FuncDecl.)
    653 		anon.build(b, anon)
    654 		fn.uniq = anon.uniq // resume after anon's unique values
    655 		if anon.FreeVars == nil {
    656 			return anon
    657 		}
    658 		v := &MakeClosure{Fn: anon}
    659 		v.setType(fn.typ(tv.Type))
    660 		for _, fv := range anon.FreeVars {
    661 			v.Bindings = append(v.Bindings, fv.outer)
    662 			fv.outer = nil
    663 		}
    664 		return fn.emit(v)
    665 
    666 	case *ast.TypeAssertExpr: // single-result form only
    667 		return emitTypeAssert(fn, b.expr(fn, e.X), fn.typ(tv.Type), e.Lparen)
    668 
    669 	case *ast.CallExpr:
    670 		if fn.info.Types[e.Fun].IsType() {
    671 			// Explicit type conversion, e.g. string(x) or big.Int(x)
    672 			x := b.expr(fn, e.Args[0])
    673 			y := emitConv(fn, x, fn.typ(tv.Type))
    674 			if y != x {
    675 				switch y := y.(type) {
    676 				case *Convert:
    677 					y.pos = e.Lparen
    678 				case *ChangeType:
    679 					y.pos = e.Lparen
    680 				case *MakeInterface:
    681 					y.pos = e.Lparen
    682 				case *SliceToArrayPointer:
    683 					y.pos = e.Lparen
    684 				case *UnOp: // conversion from slice to array.
    685 					y.pos = e.Lparen
    686 				}
    687 			}
    688 			return y
    689 		}
    690 		// Call to "intrinsic" built-ins, e.g. new, make, panic.
    691 		if id, ok := ast.Unparen(e.Fun).(*ast.Ident); ok {
    692 			if obj, ok := fn.info.Uses[id].(*types.Builtin); ok {
    693 				if v := b.builtin(fn, obj, e.Args, fn.typ(tv.Type), e.Lparen); v != nil {
    694 					return v
    695 				}
    696 			}
    697 		}
    698 		// Regular function call.
    699 		var v Call
    700 		b.setCall(fn, e, &v.Call)
    701 		v.setType(fn.typ(tv.Type))
    702 		return emitCall(fn, &v)
    703 
    704 	case *ast.UnaryExpr:
    705 		switch e.Op {
    706 		case token.AND: // &X --- potentially escaping.
    707 			addr := b.addr(fn, e.X, true)
    708 			if _, ok := ast.Unparen(e.X).(*ast.StarExpr); ok {
    709 				// &*p must panic if p is nil (http://golang.org/s/go12nil).
    710 				// For simplicity, we'll just (suboptimally) rely
    711 				// on the side effects of a load.
    712 				// TODO(adonovan): emit dedicated nilcheck.
    713 				addr.load(fn)
    714 			}
    715 			return addr.address(fn)
    716 		case token.ADD:
    717 			return b.expr(fn, e.X)
    718 		case token.NOT, token.ARROW, token.SUB, token.XOR: // ! <- - ^
    719 			v := &UnOp{
    720 				Op: e.Op,
    721 				X:  b.expr(fn, e.X),
    722 			}
    723 			v.setPos(e.OpPos)
    724 			v.setType(fn.typ(tv.Type))
    725 			return fn.emit(v)
    726 		default:
    727 			panic(e.Op)
    728 		}
    729 
    730 	case *ast.BinaryExpr:
    731 		switch e.Op {
    732 		case token.LAND, token.LOR:
    733 			return b.logicalBinop(fn, e)
    734 		case token.SHL, token.SHR:
    735 			fallthrough
    736 		case token.ADD, token.SUB, token.MUL, token.QUO, token.REM, token.AND, token.OR, token.XOR, token.AND_NOT:
    737 			return emitArith(fn, e.Op, b.expr(fn, e.X), b.expr(fn, e.Y), fn.typ(tv.Type), e.OpPos)
    738 
    739 		case token.EQL, token.NEQ, token.GTR, token.LSS, token.LEQ, token.GEQ:
    740 			cmp := emitCompare(fn, e.Op, b.expr(fn, e.X), b.expr(fn, e.Y), e.OpPos)
    741 			// The type of x==y may be UntypedBool.
    742 			return emitConv(fn, cmp, types.Default(fn.typ(tv.Type)))
    743 		default:
    744 			panic("illegal op in BinaryExpr: " + e.Op.String())
    745 		}
    746 
    747 	case *ast.SliceExpr:
    748 		var low, high, max Value
    749 		var x Value
    750 		xtyp := fn.typeOf(e.X)
    751 		switch typeparams.CoreType(xtyp).(type) {
    752 		case *types.Array:
    753 			// Potentially escaping.
    754 			x = b.addr(fn, e.X, true).address(fn)
    755 		case *types.Basic, *types.Slice, *types.Pointer: // *array
    756 			x = b.expr(fn, e.X)
    757 		default:
    758 			// core type exception?
    759 			if isBytestring(xtyp) {
    760 				x = b.expr(fn, e.X) // bytestring is handled as string and []byte.
    761 			} else {
    762 				panic("unexpected sequence type in SliceExpr")
    763 			}
    764 		}
    765 		if e.Low != nil {
    766 			low = b.expr(fn, e.Low)
    767 		}
    768 		if e.High != nil {
    769 			high = b.expr(fn, e.High)
    770 		}
    771 		if e.Slice3 {
    772 			max = b.expr(fn, e.Max)
    773 		}
    774 		v := &Slice{
    775 			X:    x,
    776 			Low:  low,
    777 			High: high,
    778 			Max:  max,
    779 		}
    780 		v.setPos(e.Lbrack)
    781 		v.setType(fn.typ(tv.Type))
    782 		return fn.emit(v)
    783 
    784 	case *ast.Ident:
    785 		obj := fn.info.Uses[e]
    786 		// Universal built-in or nil?
    787 		switch obj := obj.(type) {
    788 		case *types.Builtin:
    789 			return &Builtin{name: obj.Name(), sig: fn.instanceType(e).(*types.Signature)}
    790 		case *types.Nil:
    791 			return zeroConst(fn.instanceType(e))
    792 		}
    793 
    794 		// Package-level func or var?
    795 		// (obj must belong to same package or a direct import.)
    796 		if v := fn.Prog.packageLevelMember(obj); v != nil {
    797 			if g, ok := v.(*Global); ok {
    798 				return emitLoad(fn, g) // var (address)
    799 			}
    800 			callee := v.(*Function) // (func)
    801 			if callee.typeparams.Len() > 0 {
    802 				targs := fn.subtargs(e)
    803 				callee = callee.instance(nil, targs, b)
    804 			}
    805 			return callee
    806 		}
    807 		// Local var.
    808 		return emitLoad(fn, fn.lookup(obj.(*types.Var), false)) // var (address)
    809 
    810 	case *ast.SelectorExpr:
    811 		sel := fn.selection(e)
    812 		if sel == nil {
    813 			// builtin unsafe.{Add,Slice}
    814 			if obj, ok := fn.info.Uses[e.Sel].(*types.Builtin); ok {
    815 				return &Builtin{name: obj.Name(), sig: fn.typ(tv.Type).(*types.Signature)}
    816 			}
    817 			// qualified identifier
    818 			return b.expr(fn, e.Sel)
    819 		}
    820 		switch sel.kind {
    821 		case types.MethodExpr:
    822 			// (*T).f or T.f, the method f from the method-set of type T.
    823 			// The result is a "thunk".
    824 			targs := fn.subtargs(e.Sel)
    825 			thunk := createThunk(fn.Prog, sel, targs)
    826 			b.enqueue(thunk)
    827 			return thunk
    828 
    829 		case types.MethodVal:
    830 			// e.f where e is an expression and f is a method.
    831 			// The result is a "bound".
    832 			m := sel.obj.(*types.Func)
    833 			rt := fn.typ(recvType(m))
    834 			wantAddr := isPointer(rt)
    835 			escaping := true
    836 			v := b.receiver(fn, e.X, wantAddr, escaping, sel)
    837 
    838 			if types.IsInterface(rt) {
    839 				// If v may be an interface type I (after instantiating),
    840 				// we must emit a check that v is non-nil.
    841 				if recv, ok := types.Unalias(sel.recv).(*types.TypeParam); ok {
    842 					// Emit a nil check if any possible instantiation of the
    843 					// type parameter is an interface type.
    844 					if !typeSetIsEmpty(recv) {
    845 						// recv has a concrete term its typeset.
    846 						// So it cannot be instantiated as an interface.
    847 						//
    848 						// Example:
    849 						// func _[T interface{~int; Foo()}] () {
    850 						//    var v T
    851 						//    _ = v.Foo // <-- MethodVal
    852 						// }
    853 					} else {
    854 						// rt may be instantiated as an interface.
    855 						// Emit nil check: typeassert (any(v)).(any).
    856 						emitTypeAssert(fn, emitConv(fn, v, tEface), tEface, token.NoPos)
    857 					}
    858 				} else {
    859 					// non-type param interface
    860 					// Emit nil check: typeassert v.(I).
    861 					emitTypeAssert(fn, v, rt, e.Sel.Pos())
    862 				}
    863 			}
    864 
    865 			if rtargs := fn.subrtargs(m); len(rtargs) > 0 {
    866 				m = fn.Prog.canon.instantiateMethod(m, rtargs, fn.Prog.ctxt)
    867 			}
    868 
    869 			targs := fn.subtargs(e.Sel)
    870 			bound := createBound(fn.Prog, m, targs)
    871 			b.enqueue(bound)
    872 
    873 			// The assignment may widen a type parameter to its
    874 			// interface bound (case #3 of go.dev/issue.78110).
    875 			v = emitConv(fn, v, bound.FreeVars[0].Type())
    876 
    877 			c := &MakeClosure{
    878 				Fn:       bound,
    879 				Bindings: []Value{v},
    880 			}
    881 			c.setPos(e.Sel.Pos())
    882 			c.setType(bound.Signature)
    883 			return fn.emit(c)
    884 
    885 		case types.FieldVal:
    886 			indices := sel.index
    887 			last := len(indices) - 1
    888 			v := b.expr(fn, e.X)
    889 			v = emitImplicitSelections(fn, v, indices[:last], e.Pos())
    890 			v = emitFieldSelection(fn, v, indices[last], false, e.Sel)
    891 			return v
    892 		}
    893 
    894 		panic("unexpected expression-relative selector")
    895 
    896 	case *ast.IndexListExpr:
    897 		// f[X, Y] must be a generic function
    898 		if !instance(fn.info, e.X) {
    899 			panic("unexpected expression-could not match index list to instantiation")
    900 		}
    901 		return b.expr(fn, e.X) // Handle instantiation within the *Ident or *SelectorExpr cases.
    902 
    903 	case *ast.IndexExpr:
    904 		if instance(fn.info, e.X) {
    905 			return b.expr(fn, e.X) // Handle instantiation within the *Ident or *SelectorExpr cases.
    906 		}
    907 		// not a generic instantiation.
    908 		xt := fn.typeOf(e.X)
    909 		switch et, mode := indexType(xt); mode {
    910 		case ixVar:
    911 			// Addressable slice/array; use IndexAddr and Load.
    912 			return b.addr(fn, e, false).load(fn)
    913 
    914 		case ixArrVar, ixValue:
    915 			// An array in a register, a string or a combined type that contains
    916 			// either an [_]array (ixArrVar) or string (ixValue).
    917 
    918 			// Note: for ixArrVar and CoreType(xt)==nil can be IndexAddr and Load.
    919 			index := b.expr(fn, e.Index)
    920 			if isUntyped(index.Type()) {
    921 				index = emitConv(fn, index, tInt)
    922 			}
    923 			v := &Index{
    924 				X:     b.expr(fn, e.X),
    925 				Index: index,
    926 			}
    927 			v.setPos(e.Lbrack)
    928 			v.setType(et)
    929 			return fn.emit(v)
    930 
    931 		case ixMap:
    932 			ct := typeparams.CoreType(xt).(*types.Map)
    933 			v := &Lookup{
    934 				X:     b.expr(fn, e.X),
    935 				Index: emitConv(fn, b.expr(fn, e.Index), ct.Key()),
    936 			}
    937 			v.setPos(e.Lbrack)
    938 			v.setType(ct.Elem())
    939 			return fn.emit(v)
    940 		default:
    941 			panic("unexpected container type in IndexExpr: " + xt.String())
    942 		}
    943 
    944 	case *ast.CompositeLit, *ast.StarExpr:
    945 		// Addressable types (lvalues)
    946 		return b.addr(fn, e, false).load(fn)
    947 	}
    948 
    949 	panic(fmt.Sprintf("unexpected expr: %T", e))
    950 }
    951 
    952 // stmtList emits to fn code for all statements in list.
    953 func (b *builder) stmtList(fn *Function, list []ast.Stmt) {
    954 	for _, s := range list {
    955 		b.stmt(fn, s)
    956 	}
    957 }
    958 
    959 // receiver emits to fn code for expression e in the "receiver"
    960 // position of selection e.f (where f may be a field or a method) and
    961 // returns the effective receiver after applying the implicit field
    962 // selections of sel.
    963 //
    964 // wantAddr requests that the result is an address.  If
    965 // !sel.indirect, this may require that e be built in addr() mode; it
    966 // must thus be addressable.
    967 //
    968 // escaping is defined as per builder.addr().
    969 func (b *builder) receiver(fn *Function, e ast.Expr, wantAddr, escaping bool, sel *selection) Value {
    970 	var v Value
    971 	if wantAddr && !sel.indirect && !isPointerCore(fn.typeOf(e)) {
    972 		v = b.addr(fn, e, escaping).address(fn)
    973 	} else {
    974 		v = b.expr(fn, e)
    975 	}
    976 
    977 	last := len(sel.index) - 1
    978 	// The position of implicit selection is the position of the inducing receiver expression.
    979 	v = emitImplicitSelections(fn, v, sel.index[:last], e.Pos())
    980 	if types.IsInterface(v.Type()) {
    981 		// When v is an interface, sel.Kind()==MethodValue and v.f is invoked.
    982 		// So v is not loaded, even if v has a pointer core type.
    983 	} else if !wantAddr && isPointerCore(v.Type()) {
    984 		v = emitLoad(fn, v)
    985 	}
    986 	return v
    987 }
    988 
    989 // setCallFunc populates the function parts of a CallCommon structure
    990 // (Func, Method, Recv, Args[0]) based on the kind of invocation
    991 // occurring in e.
    992 func (b *builder) setCallFunc(fn *Function, e *ast.CallExpr, c *CallCommon) {
    993 	c.pos = e.Lparen
    994 
    995 	// Is this a (possibly generic) method call?
    996 	m := ast.Unparen(e.Fun)
    997 	switch e := m.(type) {
    998 	case *ast.IndexExpr:
    999 		m = e.X
   1000 	case *ast.IndexListExpr:
   1001 		m = e.X
   1002 	}
   1003 	if selector, ok := m.(*ast.SelectorExpr); ok {
   1004 		sel := fn.selection(selector)
   1005 		if sel != nil && sel.kind == types.MethodVal {
   1006 			obj := sel.obj.(*types.Func)
   1007 			recv := recvType(obj)
   1008 
   1009 			wantAddr := isPointer(recv)
   1010 			escaping := true
   1011 			v := b.receiver(fn, selector.X, wantAddr, escaping, sel)
   1012 			if types.IsInterface(recv) {
   1013 				// Invoke-mode call.
   1014 				c.Value = v // possibly type param
   1015 				c.Method = obj
   1016 			} else {
   1017 				// "Call"-mode call.
   1018 				targs := fn.subtargs(selector.Sel)
   1019 				c.Value = fn.Prog.objectMethod(obj, targs, b)
   1020 				c.Args = append(c.Args, v)
   1021 			}
   1022 			return
   1023 		}
   1024 
   1025 		// sel.kind==MethodExpr indicates T.f() or (*T).f():
   1026 		// a statically dispatched call to the method f in the
   1027 		// method-set of T or *T.  T may be an interface.
   1028 		//
   1029 		// e.Fun would evaluate to a concrete method, interface
   1030 		// wrapper function, or promotion wrapper.
   1031 		//
   1032 		// For now, we evaluate it in the usual way.
   1033 		//
   1034 		// TODO(adonovan): opt: inline expr() here, to make the
   1035 		// call static and to avoid generation of wrappers.
   1036 		// It's somewhat tricky as it may consume the first
   1037 		// actual parameter if the call is "invoke" mode.
   1038 		//
   1039 		// Examples:
   1040 		//  type T struct{}; func (T) f() {}   // "call" mode
   1041 		//  type T interface { f() }           // "invoke" mode
   1042 		//
   1043 		//  type S struct{ T }
   1044 		//
   1045 		//  var s S
   1046 		//  S.f(s)
   1047 		//  (*S).f(&s)
   1048 		//
   1049 		// Suggested approach:
   1050 		// - consume the first actual parameter expression
   1051 		//   and build it with b.expr().
   1052 		// - apply implicit field selections.
   1053 		// - use MethodVal logic to populate fields of c.
   1054 	}
   1055 
   1056 	// Evaluate the function operand in the usual way.
   1057 	c.Value = b.expr(fn, e.Fun)
   1058 }
   1059 
   1060 // emitCallArgs emits to f code for the actual parameters of call e to
   1061 // a (possibly built-in) function of effective type sig.
   1062 // The argument values are appended to args, which is then returned.
   1063 func (b *builder) emitCallArgs(fn *Function, sig *types.Signature, e *ast.CallExpr, args []Value) []Value {
   1064 	// f(x, y, z...): pass slice z straight through.
   1065 	if e.Ellipsis != 0 {
   1066 		for i, arg := range e.Args {
   1067 			v := emitConv(fn, b.expr(fn, arg), sig.Params().At(i).Type())
   1068 			args = append(args, v)
   1069 		}
   1070 		return args
   1071 	}
   1072 
   1073 	offset := len(args) // 1 if call has receiver, 0 otherwise
   1074 
   1075 	// Evaluate actual parameter expressions.
   1076 	//
   1077 	// If this is a chained call of the form f(g()) where g has
   1078 	// multiple return values (MRV), they are flattened out into
   1079 	// args; a suffix of them may end up in a varargs slice.
   1080 	for _, arg := range e.Args {
   1081 		v := b.expr(fn, arg)
   1082 		if ttuple, ok := v.Type().(*types.Tuple); ok { // MRV chain
   1083 			for i, n := 0, ttuple.Len(); i < n; i++ {
   1084 				args = append(args, emitExtract(fn, v, i))
   1085 			}
   1086 		} else {
   1087 			args = append(args, v)
   1088 		}
   1089 	}
   1090 
   1091 	// Actual->formal assignability conversions for normal parameters.
   1092 	np := sig.Params().Len() // number of normal parameters
   1093 	if sig.Variadic() {
   1094 		np--
   1095 	}
   1096 	for i := 0; i < np; i++ {
   1097 		args[offset+i] = emitConv(fn, args[offset+i], sig.Params().At(i).Type())
   1098 	}
   1099 
   1100 	// Actual->formal assignability conversions for variadic parameter,
   1101 	// and construction of slice.
   1102 	if sig.Variadic() {
   1103 		varargs := args[offset+np:]
   1104 		st := sig.Params().At(np).Type().(*types.Slice)
   1105 		vt := st.Elem()
   1106 		if len(varargs) == 0 {
   1107 			args = append(args, zeroConst(st))
   1108 		} else {
   1109 			// Replace a suffix of args with a slice containing it.
   1110 			at := types.NewArray(vt, int64(len(varargs)))
   1111 			a := emitNew(fn, at, token.NoPos, "varargs")
   1112 			a.setPos(e.Rparen)
   1113 			for i, arg := range varargs {
   1114 				iaddr := &IndexAddr{
   1115 					X:     a,
   1116 					Index: intConst(int64(i)),
   1117 				}
   1118 				iaddr.setType(types.NewPointer(vt))
   1119 				fn.emit(iaddr)
   1120 				emitStore(fn, iaddr, arg, arg.Pos())
   1121 			}
   1122 			s := &Slice{X: a}
   1123 			s.setType(st)
   1124 			args[offset+np] = fn.emit(s)
   1125 			args = args[:offset+np+1]
   1126 		}
   1127 	}
   1128 	return args
   1129 }
   1130 
   1131 // setCall emits to fn code to evaluate all the parameters of a function
   1132 // call e, and populates *c with those values.
   1133 func (b *builder) setCall(fn *Function, e *ast.CallExpr, c *CallCommon) {
   1134 	// First deal with the f(...) part and optional receiver.
   1135 	b.setCallFunc(fn, e, c)
   1136 
   1137 	// Then append the other actual parameters.
   1138 	sig, _ := typeparams.CoreType(fn.typeOf(e.Fun)).(*types.Signature)
   1139 	if sig == nil {
   1140 		panic(fmt.Sprintf("no signature for call of %s", e.Fun))
   1141 	}
   1142 	c.Args = b.emitCallArgs(fn, sig, e, c.Args)
   1143 }
   1144 
   1145 // assignOp emits to fn code to perform loc <op>= val.
   1146 func (b *builder) assignOp(fn *Function, loc lvalue, val Value, op token.Token, pos token.Pos) {
   1147 	loc.store(fn, emitArith(fn, op, loc.load(fn), val, loc.typ(), pos))
   1148 }
   1149 
   1150 // localValueSpec emits to fn code to define all of the vars in the
   1151 // function-local ValueSpec, spec.
   1152 func (b *builder) localValueSpec(fn *Function, spec *ast.ValueSpec) {
   1153 	switch {
   1154 	case len(spec.Values) == len(spec.Names):
   1155 		// e.g. var x, y = 0, 1
   1156 		// 1:1 assignment
   1157 		for i, id := range spec.Names {
   1158 			if !isBlankIdent(id) {
   1159 				emitLocalVar(fn, identVar(fn, id))
   1160 			}
   1161 			lval := b.addr(fn, id, false) // non-escaping
   1162 			b.assign(fn, lval, spec.Values[i], true, nil)
   1163 		}
   1164 
   1165 	case len(spec.Values) == 0:
   1166 		// e.g. var x, y int
   1167 		// Locals are implicitly zero-initialized.
   1168 		for _, id := range spec.Names {
   1169 			if !isBlankIdent(id) {
   1170 				lhs := emitLocalVar(fn, identVar(fn, id))
   1171 				if fn.debugInfo() {
   1172 					emitDebugRef(fn, id, lhs, true)
   1173 				}
   1174 			}
   1175 		}
   1176 
   1177 	default:
   1178 		// e.g. var x, y = pos()
   1179 		tuple := b.exprN(fn, spec.Values[0])
   1180 		for i, id := range spec.Names {
   1181 			if !isBlankIdent(id) {
   1182 				emitLocalVar(fn, identVar(fn, id))
   1183 				lhs := b.addr(fn, id, false) // non-escaping
   1184 				lhs.store(fn, emitExtract(fn, tuple, i))
   1185 			}
   1186 		}
   1187 	}
   1188 }
   1189 
   1190 // assignStmt emits code to fn for a parallel assignment of rhss to lhss.
   1191 // isDef is true if this is a short variable declaration (:=).
   1192 //
   1193 // Note the similarity with localValueSpec.
   1194 func (b *builder) assignStmt(fn *Function, lhss, rhss []ast.Expr, isDef bool) {
   1195 	// Side effects of all LHSs and RHSs must occur in left-to-right order.
   1196 	lvals := make([]lvalue, len(lhss))
   1197 	isZero := make([]bool, len(lhss))
   1198 	for i, lhs := range lhss {
   1199 		var lval lvalue = blank{}
   1200 		if !isBlankIdent(lhs) {
   1201 			if isDef {
   1202 				if obj, ok := fn.info.Defs[lhs.(*ast.Ident)].(*types.Var); ok {
   1203 					emitLocalVar(fn, obj)
   1204 					isZero[i] = true
   1205 				}
   1206 			}
   1207 			lval = b.addr(fn, lhs, false) // non-escaping
   1208 		}
   1209 		lvals[i] = lval
   1210 	}
   1211 	if len(lhss) == len(rhss) {
   1212 		// Simple assignment:   x     = f()        (!isDef)
   1213 		// Parallel assignment: x, y  = f(), g()   (!isDef)
   1214 		// or short var decl:   x, y := f(), g()   (isDef)
   1215 		//
   1216 		// In all cases, the RHSs may refer to the LHSs,
   1217 		// so we need a storebuf.
   1218 		var sb storebuf
   1219 		for i := range rhss {
   1220 			b.assign(fn, lvals[i], rhss[i], isZero[i], &sb)
   1221 		}
   1222 		sb.emit(fn)
   1223 	} else {
   1224 		// e.g. x, y = pos()
   1225 		tuple := b.exprN(fn, rhss[0])
   1226 		emitDebugRef(fn, rhss[0], tuple, false)
   1227 		for i, lval := range lvals {
   1228 			lval.store(fn, emitExtract(fn, tuple, i))
   1229 		}
   1230 	}
   1231 }
   1232 
   1233 // arrayLen returns the length of the array whose composite literal elements are elts.
   1234 func (b *builder) arrayLen(fn *Function, elts []ast.Expr) int64 {
   1235 	var max int64 = -1
   1236 	var i int64 = -1
   1237 	for _, e := range elts {
   1238 		if kv, ok := e.(*ast.KeyValueExpr); ok {
   1239 			i = b.expr(fn, kv.Key).(*Const).Int64()
   1240 		} else {
   1241 			i++
   1242 		}
   1243 		if i > max {
   1244 			max = i
   1245 		}
   1246 	}
   1247 	return max + 1
   1248 }
   1249 
   1250 // compLit emits to fn code to initialize a composite literal e at
   1251 // address addr with type typ.
   1252 //
   1253 // Nested composite literals are recursively initialized in place
   1254 // where possible. If isZero is true, compLit assumes that addr
   1255 // holds the zero value for typ.
   1256 //
   1257 // Because the elements of a composite literal may refer to the
   1258 // variables being updated, as in the second line below,
   1259 //
   1260 //	x := T{a: 1}
   1261 //	x = T{a: x.a}
   1262 //
   1263 // all the reads must occur before all the writes. Thus all stores to
   1264 // loc are emitted to the storebuf sb for later execution.
   1265 //
   1266 // A CompositeLit may have pointer type only in the recursive (nested)
   1267 // case when the type name is implicit.  e.g. in []*T{{}}, the inner
   1268 // literal has type *T behaves like &T{}.
   1269 // In that case, addr must hold a T, not a *T.
   1270 func (b *builder) compLit(fn *Function, addr Value, e *ast.CompositeLit, isZero bool, sb *storebuf) {
   1271 	typ := typeparams.Deref(fn.typeOf(e)) // retain the named/alias/param type, if any
   1272 	switch t := typeparams.CoreType(typ).(type) {
   1273 	case *types.Struct:
   1274 		if !isZero && len(e.Elts) != t.NumFields() {
   1275 			// memclear
   1276 			zt := typeparams.MustDeref(addr.Type())
   1277 			sb.store(&address{addr, e.Lbrace, nil}, zeroConst(zt))
   1278 			isZero = true
   1279 		}
   1280 		var fIndices []int
   1281 		for i, e := range e.Elts {
   1282 			var (
   1283 				pos   token.Pos
   1284 				fType types.Type
   1285 			)
   1286 
   1287 			if kv, ok := e.(*ast.KeyValueExpr); ok { // tagged field
   1288 				fname := kv.Key.(*ast.Ident).Name
   1289 				obj, index, _ := types.LookupFieldOrMethod(t, true, fn.declaredPackage().Pkg, fname)
   1290 				fIndices = append(fIndices[:0], index...)
   1291 				pos = kv.Colon
   1292 				e = kv.Value
   1293 				fType = obj.Type()
   1294 			} else { // untagged field
   1295 				fIndices = append(fIndices[:0], i)
   1296 				pos = e.Pos()
   1297 				fType = t.Field(i).Type()
   1298 			}
   1299 
   1300 			last := len(fIndices) - 1
   1301 			v := emitImplicitSelections(fn, addr, fIndices[:last], pos)
   1302 
   1303 			faddr := &FieldAddr{
   1304 				X:     v,
   1305 				Field: fIndices[last],
   1306 			}
   1307 			faddr.setPos(pos)
   1308 			faddr.setType(types.NewPointer(fType))
   1309 			fn.emit(faddr)
   1310 			b.assign(fn, &address{addr: faddr, pos: pos, expr: e}, e, isZero, sb)
   1311 		}
   1312 
   1313 	case *types.Array, *types.Slice:
   1314 		var at *types.Array
   1315 		var array Value
   1316 		switch t := t.(type) {
   1317 		case *types.Slice:
   1318 			at = types.NewArray(t.Elem(), b.arrayLen(fn, e.Elts))
   1319 			array = emitNew(fn, at, e.Lbrace, "slicelit")
   1320 		case *types.Array:
   1321 			at = t
   1322 			array = addr
   1323 
   1324 			if !isZero && int64(len(e.Elts)) != at.Len() {
   1325 				// memclear
   1326 				zt := typeparams.MustDeref(array.Type())
   1327 				sb.store(&address{array, e.Lbrace, nil}, zeroConst(zt))
   1328 			}
   1329 		}
   1330 
   1331 		var idx *Const
   1332 		for _, e := range e.Elts {
   1333 			pos := e.Pos()
   1334 			if kv, ok := e.(*ast.KeyValueExpr); ok {
   1335 				idx = b.expr(fn, kv.Key).(*Const)
   1336 				pos = kv.Colon
   1337 				e = kv.Value
   1338 			} else {
   1339 				var idxval int64
   1340 				if idx != nil {
   1341 					idxval = idx.Int64() + 1
   1342 				}
   1343 				idx = intConst(idxval)
   1344 			}
   1345 			iaddr := &IndexAddr{
   1346 				X:     array,
   1347 				Index: idx,
   1348 			}
   1349 			iaddr.setType(types.NewPointer(at.Elem()))
   1350 			fn.emit(iaddr)
   1351 			if t != at { // slice
   1352 				// backing array is unaliased => storebuf not needed.
   1353 				b.assign(fn, &address{addr: iaddr, pos: pos, expr: e}, e, true, nil)
   1354 			} else {
   1355 				b.assign(fn, &address{addr: iaddr, pos: pos, expr: e}, e, true, sb)
   1356 			}
   1357 		}
   1358 
   1359 		if t != at { // slice
   1360 			s := &Slice{X: array}
   1361 			s.setPos(e.Lbrace)
   1362 			s.setType(typ)
   1363 			sb.store(&address{addr: addr, pos: e.Lbrace, expr: e}, fn.emit(s))
   1364 		}
   1365 
   1366 	case *types.Map:
   1367 		m := &MakeMap{Reserve: intConst(int64(len(e.Elts)))}
   1368 		m.setPos(e.Lbrace)
   1369 		m.setType(typ)
   1370 		fn.emit(m)
   1371 		for _, e := range e.Elts {
   1372 			e := e.(*ast.KeyValueExpr)
   1373 
   1374 			// If a key expression in a map literal is itself a
   1375 			// composite literal, the type may be omitted.
   1376 			// For example:
   1377 			//	map[*struct{}]bool{{}: true}
   1378 			// An &-operation may be implied:
   1379 			//	map[*struct{}]bool{&struct{}{}: true}
   1380 			wantAddr := false
   1381 			if _, ok := ast.Unparen(e.Key).(*ast.CompositeLit); ok {
   1382 				wantAddr = isPointerCore(t.Key())
   1383 			}
   1384 
   1385 			var key Value
   1386 			if wantAddr {
   1387 				// A CompositeLit never evaluates to a pointer,
   1388 				// so if the type of the location is a pointer,
   1389 				// an &-operation is implied.
   1390 				key = b.addr(fn, e.Key, true).address(fn)
   1391 			} else {
   1392 				key = b.expr(fn, e.Key)
   1393 			}
   1394 
   1395 			loc := element{
   1396 				m:   m,
   1397 				k:   emitConv(fn, key, t.Key()),
   1398 				t:   t.Elem(),
   1399 				pos: e.Colon,
   1400 			}
   1401 
   1402 			// We call assign() only because it takes care
   1403 			// of any &-operation required in the recursive
   1404 			// case, e.g.,
   1405 			// map[int]*struct{}{0: {}} implies &struct{}{}.
   1406 			// In-place update is of course impossible,
   1407 			// and no storebuf is needed.
   1408 			b.assign(fn, &loc, e.Value, true, nil)
   1409 		}
   1410 		sb.store(&address{addr: addr, pos: e.Lbrace, expr: e}, m)
   1411 
   1412 	default:
   1413 		panic("unexpected CompositeLit type: " + typ.String())
   1414 	}
   1415 }
   1416 
   1417 // switchStmt emits to fn code for the switch statement s, optionally
   1418 // labelled by label.
   1419 func (b *builder) switchStmt(fn *Function, s *ast.SwitchStmt, label *lblock) {
   1420 	// We treat SwitchStmt like a sequential if-else chain.
   1421 	// Multiway dispatch can be recovered later by ssautil.Switches()
   1422 	// to those cases that are free of side effects.
   1423 	if s.Init != nil {
   1424 		b.stmt(fn, s.Init)
   1425 	}
   1426 	var tag Value = vTrue
   1427 	if s.Tag != nil {
   1428 		tag = b.expr(fn, s.Tag)
   1429 	}
   1430 	done := fn.newBasicBlock("switch.done")
   1431 	if label != nil {
   1432 		label._break = done
   1433 	}
   1434 	// We pull the default case (if present) down to the end.
   1435 	// But each fallthrough label must point to the next
   1436 	// body block in source order, so we preallocate a
   1437 	// body block (fallthru) for the next case.
   1438 	// Unfortunately this makes for a confusing block order.
   1439 	var dfltBody *[]ast.Stmt
   1440 	var dfltFallthrough *BasicBlock
   1441 	var fallthru, dfltBlock *BasicBlock
   1442 	ncases := len(s.Body.List)
   1443 	for i, clause := range s.Body.List {
   1444 		body := fallthru
   1445 		if body == nil {
   1446 			body = fn.newBasicBlock("switch.body") // first case only
   1447 		}
   1448 
   1449 		// Preallocate body block for the next case.
   1450 		fallthru = done
   1451 		if i+1 < ncases {
   1452 			fallthru = fn.newBasicBlock("switch.body")
   1453 		}
   1454 
   1455 		cc := clause.(*ast.CaseClause)
   1456 		if cc.List == nil {
   1457 			// Default case.
   1458 			dfltBody = &cc.Body
   1459 			dfltFallthrough = fallthru
   1460 			dfltBlock = body
   1461 			continue
   1462 		}
   1463 
   1464 		var nextCond *BasicBlock
   1465 		for _, cond := range cc.List {
   1466 			nextCond = fn.newBasicBlock("switch.next")
   1467 			// For boolean switches, emit short-circuit control flow,
   1468 			// just like an if/else-chain.
   1469 			if tag == vTrue && !isNonTypeParamInterface(fn.info.Types[cond].Type) {
   1470 				b.cond(fn, cond, body, nextCond)
   1471 			} else {
   1472 				c := emitCompare(fn, token.EQL, tag, b.expr(fn, cond), cond.Pos())
   1473 				emitIf(fn, c, body, nextCond)
   1474 			}
   1475 			fn.currentBlock = nextCond
   1476 		}
   1477 		fn.currentBlock = body
   1478 		fn.targets = &targets{
   1479 			tail:         fn.targets,
   1480 			_break:       done,
   1481 			_fallthrough: fallthru,
   1482 		}
   1483 		b.stmtList(fn, cc.Body)
   1484 		fn.targets = fn.targets.tail
   1485 		emitJump(fn, done)
   1486 		fn.currentBlock = nextCond
   1487 	}
   1488 	if dfltBlock != nil {
   1489 		emitJump(fn, dfltBlock)
   1490 		fn.currentBlock = dfltBlock
   1491 		fn.targets = &targets{
   1492 			tail:         fn.targets,
   1493 			_break:       done,
   1494 			_fallthrough: dfltFallthrough,
   1495 		}
   1496 		b.stmtList(fn, *dfltBody)
   1497 		fn.targets = fn.targets.tail
   1498 	}
   1499 	emitJump(fn, done)
   1500 	fn.currentBlock = done
   1501 }
   1502 
   1503 // typeSwitchStmt emits to fn code for the type switch statement s, optionally
   1504 // labelled by label.
   1505 func (b *builder) typeSwitchStmt(fn *Function, s *ast.TypeSwitchStmt, label *lblock) {
   1506 	// We treat TypeSwitchStmt like a sequential if-else chain.
   1507 	// Multiway dispatch can be recovered later by ssautil.Switches().
   1508 
   1509 	// Typeswitch lowering:
   1510 	//
   1511 	// var x X
   1512 	// switch y := x.(type) {
   1513 	// case T1, T2: S1                  // >1 	(y := x)
   1514 	// case nil:    SN                  // nil 	(y := x)
   1515 	// default:     SD                  // 0 types 	(y := x)
   1516 	// case T3:     S3                  // 1 type 	(y := x.(T3))
   1517 	// }
   1518 	//
   1519 	//      ...s.Init...
   1520 	// 	x := eval x
   1521 	// .caseT1:
   1522 	// 	t1, ok1 := typeswitch,ok x <T1>
   1523 	// 	if ok1 then goto S1 else goto .caseT2
   1524 	// .caseT2:
   1525 	// 	t2, ok2 := typeswitch,ok x <T2>
   1526 	// 	if ok2 then goto S1 else goto .caseNil
   1527 	// .S1:
   1528 	//      y := x
   1529 	// 	...S1...
   1530 	// 	goto done
   1531 	// .caseNil:
   1532 	// 	if t2, ok2 := typeswitch,ok x <T2>
   1533 	// 	if x == nil then goto SN else goto .caseT3
   1534 	// .SN:
   1535 	//      y := x
   1536 	// 	...SN...
   1537 	// 	goto done
   1538 	// .caseT3:
   1539 	// 	t3, ok3 := typeswitch,ok x <T3>
   1540 	// 	if ok3 then goto S3 else goto default
   1541 	// .S3:
   1542 	//      y := t3
   1543 	// 	...S3...
   1544 	// 	goto done
   1545 	// .default:
   1546 	//      y := x
   1547 	// 	...SD...
   1548 	// 	goto done
   1549 	// .done:
   1550 	if s.Init != nil {
   1551 		b.stmt(fn, s.Init)
   1552 	}
   1553 
   1554 	var x Value
   1555 	switch ass := s.Assign.(type) {
   1556 	case *ast.ExprStmt: // x.(type)
   1557 		x = b.expr(fn, ast.Unparen(ass.X).(*ast.TypeAssertExpr).X)
   1558 	case *ast.AssignStmt: // y := x.(type)
   1559 		x = b.expr(fn, ast.Unparen(ass.Rhs[0]).(*ast.TypeAssertExpr).X)
   1560 	}
   1561 
   1562 	done := fn.newBasicBlock("typeswitch.done")
   1563 	if label != nil {
   1564 		label._break = done
   1565 	}
   1566 	var default_ *ast.CaseClause
   1567 	for _, clause := range s.Body.List {
   1568 		cc := clause.(*ast.CaseClause)
   1569 		if cc.List == nil {
   1570 			default_ = cc
   1571 			continue
   1572 		}
   1573 		body := fn.newBasicBlock("typeswitch.body")
   1574 		var next *BasicBlock
   1575 		var casetype types.Type
   1576 		var ti Value // ti, ok := typeassert,ok x <Ti>
   1577 		for _, cond := range cc.List {
   1578 			next = fn.newBasicBlock("typeswitch.next")
   1579 			casetype = fn.typeOf(cond)
   1580 			var condv Value
   1581 			if casetype == tUntypedNil {
   1582 				condv = emitCompare(fn, token.EQL, x, zeroConst(x.Type()), cond.Pos())
   1583 				ti = x
   1584 			} else {
   1585 				yok := emitTypeTest(fn, x, casetype, cc.Case)
   1586 				ti = emitExtract(fn, yok, 0)
   1587 				condv = emitExtract(fn, yok, 1)
   1588 			}
   1589 			emitIf(fn, condv, body, next)
   1590 			fn.currentBlock = next
   1591 		}
   1592 		if len(cc.List) != 1 {
   1593 			ti = x
   1594 		}
   1595 		fn.currentBlock = body
   1596 		b.typeCaseBody(fn, cc, ti, done)
   1597 		fn.currentBlock = next
   1598 	}
   1599 	if default_ != nil {
   1600 		b.typeCaseBody(fn, default_, x, done)
   1601 	} else {
   1602 		emitJump(fn, done)
   1603 	}
   1604 	fn.currentBlock = done
   1605 }
   1606 
   1607 func (b *builder) typeCaseBody(fn *Function, cc *ast.CaseClause, x Value, done *BasicBlock) {
   1608 	if obj, ok := fn.info.Implicits[cc].(*types.Var); ok {
   1609 		// In a switch y := x.(type), each case clause
   1610 		// implicitly declares a distinct object y.
   1611 		// In a single-type case, y has that type.
   1612 		// In multi-type cases, 'case nil' and default,
   1613 		// y has the same type as the interface operand.
   1614 		emitStore(fn, emitLocalVar(fn, obj), x, obj.Pos())
   1615 	}
   1616 	fn.targets = &targets{
   1617 		tail:   fn.targets,
   1618 		_break: done,
   1619 	}
   1620 	b.stmtList(fn, cc.Body)
   1621 	fn.targets = fn.targets.tail
   1622 	emitJump(fn, done)
   1623 }
   1624 
   1625 // selectStmt emits to fn code for the select statement s, optionally
   1626 // labelled by label.
   1627 func (b *builder) selectStmt(fn *Function, s *ast.SelectStmt, label *lblock) {
   1628 	// A blocking select of a single case degenerates to a
   1629 	// simple send or receive.
   1630 	// TODO(adonovan): opt: is this optimization worth its weight?
   1631 	if len(s.Body.List) == 1 {
   1632 		clause := s.Body.List[0].(*ast.CommClause)
   1633 		if clause.Comm != nil {
   1634 			b.stmt(fn, clause.Comm)
   1635 			done := fn.newBasicBlock("select.done")
   1636 			if label != nil {
   1637 				label._break = done
   1638 			}
   1639 			fn.targets = &targets{
   1640 				tail:   fn.targets,
   1641 				_break: done,
   1642 			}
   1643 			b.stmtList(fn, clause.Body)
   1644 			fn.targets = fn.targets.tail
   1645 			emitJump(fn, done)
   1646 			fn.currentBlock = done
   1647 			return
   1648 		}
   1649 	}
   1650 
   1651 	// First evaluate all channels in all cases, and find
   1652 	// the directions of each state.
   1653 	var states []*SelectState
   1654 	blocking := true
   1655 	debugInfo := fn.debugInfo()
   1656 	for _, clause := range s.Body.List {
   1657 		var st *SelectState
   1658 		switch comm := clause.(*ast.CommClause).Comm.(type) {
   1659 		case nil: // default case
   1660 			blocking = false
   1661 			continue
   1662 
   1663 		case *ast.SendStmt: // ch<- i
   1664 			ch := b.expr(fn, comm.Chan)
   1665 			chtyp := typeparams.CoreType(fn.typ(ch.Type())).(*types.Chan)
   1666 			st = &SelectState{
   1667 				Dir:  types.SendOnly,
   1668 				Chan: ch,
   1669 				Send: emitConv(fn, b.expr(fn, comm.Value), chtyp.Elem()),
   1670 				Pos:  comm.Arrow,
   1671 			}
   1672 			if debugInfo {
   1673 				st.DebugNode = comm
   1674 			}
   1675 
   1676 		case *ast.AssignStmt: // x := <-ch
   1677 			recv := ast.Unparen(comm.Rhs[0]).(*ast.UnaryExpr)
   1678 			st = &SelectState{
   1679 				Dir:  types.RecvOnly,
   1680 				Chan: b.expr(fn, recv.X),
   1681 				Pos:  recv.OpPos,
   1682 			}
   1683 			if debugInfo {
   1684 				st.DebugNode = recv
   1685 			}
   1686 
   1687 		case *ast.ExprStmt: // <-ch
   1688 			recv := ast.Unparen(comm.X).(*ast.UnaryExpr)
   1689 			st = &SelectState{
   1690 				Dir:  types.RecvOnly,
   1691 				Chan: b.expr(fn, recv.X),
   1692 				Pos:  recv.OpPos,
   1693 			}
   1694 			if debugInfo {
   1695 				st.DebugNode = recv
   1696 			}
   1697 		}
   1698 		states = append(states, st)
   1699 	}
   1700 
   1701 	// We dispatch on the (fair) result of Select using a
   1702 	// sequential if-else chain, in effect:
   1703 	//
   1704 	// idx, recvOk, r0...r_n-1 := select(...)
   1705 	// if idx == 0 {  // receive on channel 0  (first receive => r0)
   1706 	//     x, ok := r0, recvOk
   1707 	//     ...state0...
   1708 	// } else if v == 1 {   // send on channel 1
   1709 	//     ...state1...
   1710 	// } else {
   1711 	//     ...default...
   1712 	// }
   1713 	sel := &Select{
   1714 		States:   states,
   1715 		Blocking: blocking,
   1716 	}
   1717 	sel.setPos(s.Select)
   1718 	var vars []*types.Var
   1719 	vars = append(vars, varIndex, varOk)
   1720 	for _, st := range states {
   1721 		if st.Dir == types.RecvOnly {
   1722 			chtyp := typeparams.CoreType(fn.typ(st.Chan.Type())).(*types.Chan)
   1723 			vars = append(vars, newVar("", chtyp.Elem()))
   1724 		}
   1725 	}
   1726 	sel.setType(types.NewTuple(vars...))
   1727 
   1728 	fn.emit(sel)
   1729 	idx := emitExtract(fn, sel, 0)
   1730 
   1731 	done := fn.newBasicBlock("select.done")
   1732 	if label != nil {
   1733 		label._break = done
   1734 	}
   1735 
   1736 	var defaultBody *[]ast.Stmt
   1737 	state := 0
   1738 	r := 2 // index in 'sel' tuple of value; increments if st.Dir==RECV
   1739 	for _, cc := range s.Body.List {
   1740 		clause := cc.(*ast.CommClause)
   1741 		if clause.Comm == nil {
   1742 			defaultBody = &clause.Body
   1743 			continue
   1744 		}
   1745 		body := fn.newBasicBlock("select.body")
   1746 		next := fn.newBasicBlock("select.next")
   1747 		emitIf(fn, emitCompare(fn, token.EQL, idx, intConst(int64(state)), token.NoPos), body, next)
   1748 		fn.currentBlock = body
   1749 		fn.targets = &targets{
   1750 			tail:   fn.targets,
   1751 			_break: done,
   1752 		}
   1753 		switch comm := clause.Comm.(type) {
   1754 		case *ast.ExprStmt: // <-ch
   1755 			if debugInfo {
   1756 				v := emitExtract(fn, sel, r)
   1757 				emitDebugRef(fn, states[state].DebugNode.(ast.Expr), v, false)
   1758 			}
   1759 			r++
   1760 
   1761 		case *ast.AssignStmt: // x := <-states[state].Chan
   1762 			if comm.Tok == token.DEFINE {
   1763 				emitLocalVar(fn, identVar(fn, comm.Lhs[0].(*ast.Ident)))
   1764 			}
   1765 			x := b.addr(fn, comm.Lhs[0], false) // non-escaping
   1766 			v := emitExtract(fn, sel, r)
   1767 			if debugInfo {
   1768 				emitDebugRef(fn, states[state].DebugNode.(ast.Expr), v, false)
   1769 			}
   1770 			x.store(fn, v)
   1771 
   1772 			if len(comm.Lhs) == 2 { // x, ok := ...
   1773 				if comm.Tok == token.DEFINE {
   1774 					emitLocalVar(fn, identVar(fn, comm.Lhs[1].(*ast.Ident)))
   1775 				}
   1776 				ok := b.addr(fn, comm.Lhs[1], false) // non-escaping
   1777 				ok.store(fn, emitExtract(fn, sel, 1))
   1778 			}
   1779 			r++
   1780 		}
   1781 		b.stmtList(fn, clause.Body)
   1782 		fn.targets = fn.targets.tail
   1783 		emitJump(fn, done)
   1784 		fn.currentBlock = next
   1785 		state++
   1786 	}
   1787 	if defaultBody != nil {
   1788 		fn.targets = &targets{
   1789 			tail:   fn.targets,
   1790 			_break: done,
   1791 		}
   1792 		b.stmtList(fn, *defaultBody)
   1793 		fn.targets = fn.targets.tail
   1794 	} else {
   1795 		// A blocking select must match some case.
   1796 		// (This should really be a runtime.errorString, not a string.)
   1797 		fn.emit(&Panic{
   1798 			X: emitConv(fn, stringConst("blocking select matched no case"), tEface),
   1799 		})
   1800 		fn.currentBlock = fn.newBasicBlock("unreachable")
   1801 	}
   1802 	emitJump(fn, done)
   1803 	fn.currentBlock = done
   1804 }
   1805 
   1806 // forStmt emits to fn code for the for statement s, optionally
   1807 // labelled by label.
   1808 func (b *builder) forStmt(fn *Function, s *ast.ForStmt, label *lblock) {
   1809 	// Use forStmtGo122 instead if it applies.
   1810 	if s.Init != nil {
   1811 		if assign, ok := s.Init.(*ast.AssignStmt); ok && assign.Tok == token.DEFINE {
   1812 			if versions.AtLeast(fn.goversion, versions.Go1_22) {
   1813 				b.forStmtGo122(fn, s, label)
   1814 				return
   1815 			}
   1816 		}
   1817 	}
   1818 
   1819 	//     ...init...
   1820 	//     jump loop
   1821 	// loop:
   1822 	//     if cond goto body else done
   1823 	// body:
   1824 	//     ...body...
   1825 	//     jump post
   1826 	// post:                                 (target of continue)
   1827 	//     ...post...
   1828 	//     jump loop
   1829 	// done:                                 (target of break)
   1830 	if s.Init != nil {
   1831 		b.stmt(fn, s.Init)
   1832 	}
   1833 
   1834 	body := fn.newBasicBlock("for.body")
   1835 	done := fn.newBasicBlock("for.done") // target of 'break'
   1836 	loop := body                         // target of back-edge
   1837 	if s.Cond != nil {
   1838 		loop = fn.newBasicBlock("for.loop")
   1839 	}
   1840 	cont := loop // target of 'continue'
   1841 	if s.Post != nil {
   1842 		cont = fn.newBasicBlock("for.post")
   1843 	}
   1844 	if label != nil {
   1845 		label._break = done
   1846 		label._continue = cont
   1847 	}
   1848 	emitJump(fn, loop)
   1849 	fn.currentBlock = loop
   1850 	if loop != body {
   1851 		b.cond(fn, s.Cond, body, done)
   1852 		fn.currentBlock = body
   1853 	}
   1854 	fn.targets = &targets{
   1855 		tail:      fn.targets,
   1856 		_break:    done,
   1857 		_continue: cont,
   1858 	}
   1859 	b.stmt(fn, s.Body)
   1860 	fn.targets = fn.targets.tail
   1861 	emitJump(fn, cont)
   1862 
   1863 	if s.Post != nil {
   1864 		fn.currentBlock = cont
   1865 		b.stmt(fn, s.Post)
   1866 		emitJump(fn, loop) // back-edge
   1867 	}
   1868 	fn.currentBlock = done
   1869 }
   1870 
   1871 // forStmtGo122 emits to fn code for the for statement s, optionally
   1872 // labelled by label. s must define its variables.
   1873 //
   1874 // This allocates once per loop iteration. This is only correct in
   1875 // GoVersions >= go1.22.
   1876 func (b *builder) forStmtGo122(fn *Function, s *ast.ForStmt, label *lblock) {
   1877 	//     i_outer = alloc[T]
   1878 	//     *i_outer = ...init...        // under objects[i] = i_outer
   1879 	//     jump loop
   1880 	// loop:
   1881 	//     i = phi [head: i_outer, loop: i_next]
   1882 	//     ...cond...                   // under objects[i] = i
   1883 	//     if cond goto body else done
   1884 	// body:
   1885 	//     ...body...                   // under objects[i] = i (same as loop)
   1886 	//     jump post
   1887 	// post:
   1888 	//     tmp = *i
   1889 	//     i_next = alloc[T]
   1890 	//     *i_next = tmp
   1891 	//     ...post...                   // under objects[i] = i_next
   1892 	//     goto loop
   1893 	// done:
   1894 
   1895 	init := s.Init.(*ast.AssignStmt)
   1896 	startingBlocks := len(fn.Blocks)
   1897 
   1898 	pre := fn.currentBlock               // current block before starting
   1899 	loop := fn.newBasicBlock("for.loop") // target of back-edge
   1900 	body := fn.newBasicBlock("for.body")
   1901 	post := fn.newBasicBlock("for.post") // target of 'continue'
   1902 	done := fn.newBasicBlock("for.done") // target of 'break'
   1903 
   1904 	// For each of the n loop variables, we create five SSA values,
   1905 	// outer, phi, next, load, and store in pre, loop, and post.
   1906 	// There is no limit on n.
   1907 	type loopVar struct {
   1908 		obj   *types.Var
   1909 		outer *Alloc
   1910 		phi   *Phi
   1911 		load  *UnOp
   1912 		next  *Alloc
   1913 		store *Store
   1914 	}
   1915 	vars := make([]loopVar, len(init.Lhs))
   1916 	for i, lhs := range init.Lhs {
   1917 		v := identVar(fn, lhs.(*ast.Ident))
   1918 		typ := fn.typ(v.Type())
   1919 
   1920 		fn.currentBlock = pre
   1921 		outer := emitLocal(fn, typ, v.Pos(), v.Name())
   1922 
   1923 		fn.currentBlock = loop
   1924 		phi := &Phi{Comment: v.Name()}
   1925 		phi.pos = v.Pos()
   1926 		phi.typ = outer.Type()
   1927 		fn.emit(phi)
   1928 
   1929 		fn.currentBlock = post
   1930 		// If next is local, it reuses the address and zeroes the old value so
   1931 		// load before allocating next.
   1932 		load := emitLoad(fn, phi)
   1933 		next := emitLocal(fn, typ, v.Pos(), v.Name())
   1934 		store := emitStore(fn, next, load, token.NoPos)
   1935 
   1936 		phi.Edges = []Value{outer, next} // pre edge is emitted before post edge.
   1937 
   1938 		vars[i] = loopVar{v, outer, phi, load, next, store}
   1939 	}
   1940 
   1941 	// ...init... under fn.objects[v] = i_outer
   1942 	fn.currentBlock = pre
   1943 	for _, v := range vars {
   1944 		fn.vars[v.obj] = v.outer
   1945 	}
   1946 	const isDef = false // assign to already-allocated outers
   1947 	b.assignStmt(fn, init.Lhs, init.Rhs, isDef)
   1948 	if label != nil {
   1949 		label._break = done
   1950 		label._continue = post
   1951 	}
   1952 	emitJump(fn, loop)
   1953 
   1954 	// ...cond... under fn.objects[v] = i
   1955 	fn.currentBlock = loop
   1956 	for _, v := range vars {
   1957 		fn.vars[v.obj] = v.phi
   1958 	}
   1959 	if s.Cond != nil {
   1960 		b.cond(fn, s.Cond, body, done)
   1961 	} else {
   1962 		emitJump(fn, body)
   1963 	}
   1964 
   1965 	// ...body... under fn.objects[v] = i
   1966 	fn.currentBlock = body
   1967 	fn.targets = &targets{
   1968 		tail:      fn.targets,
   1969 		_break:    done,
   1970 		_continue: post,
   1971 	}
   1972 	b.stmt(fn, s.Body)
   1973 	fn.targets = fn.targets.tail
   1974 	emitJump(fn, post)
   1975 
   1976 	// ...post... under fn.objects[v] = i_next
   1977 	for _, v := range vars {
   1978 		fn.vars[v.obj] = v.next
   1979 	}
   1980 	fn.currentBlock = post
   1981 	if s.Post != nil {
   1982 		b.stmt(fn, s.Post)
   1983 	}
   1984 	emitJump(fn, loop) // back-edge
   1985 	fn.currentBlock = done
   1986 
   1987 	// For each loop variable that does not escape,
   1988 	// (the common case), fuse its next cells into its
   1989 	// (local) outer cell as they have disjoint live ranges.
   1990 	//
   1991 	// It is sufficient to test whether i_next escapes,
   1992 	// because its Heap flag will be marked true if either
   1993 	// the cond or post expression causes i to escape
   1994 	// (because escape distributes over phi).
   1995 	var nlocals int
   1996 	for _, v := range vars {
   1997 		if !v.next.Heap {
   1998 			nlocals++
   1999 		}
   2000 	}
   2001 	if nlocals > 0 {
   2002 		replace := make(map[Value]Value, 2*nlocals)
   2003 		dead := make(map[Instruction]bool, 4*nlocals)
   2004 		for _, v := range vars {
   2005 			if !v.next.Heap {
   2006 				replace[v.next] = v.outer
   2007 				replace[v.phi] = v.outer
   2008 				dead[v.phi], dead[v.next], dead[v.load], dead[v.store] = true, true, true, true
   2009 			}
   2010 		}
   2011 
   2012 		// Replace all uses of i_next and phi with i_outer.
   2013 		// Referrers have not been built for fn yet so only update Instruction operands.
   2014 		// We need only look within the blocks added by the loop.
   2015 		var operands []*Value // recycle storage
   2016 		for _, b := range fn.Blocks[startingBlocks:] {
   2017 			for _, instr := range b.Instrs {
   2018 				operands = instr.Operands(operands[:0])
   2019 				for _, ptr := range operands {
   2020 					k := *ptr
   2021 					if v := replace[k]; v != nil {
   2022 						*ptr = v
   2023 					}
   2024 				}
   2025 			}
   2026 		}
   2027 
   2028 		// Remove instructions for phi, load, and store.
   2029 		// lift() will remove the unused i_next *Alloc.
   2030 		isDead := func(i Instruction) bool { return dead[i] }
   2031 		loop.Instrs = slices.DeleteFunc(loop.Instrs, isDead)
   2032 		post.Instrs = slices.DeleteFunc(post.Instrs, isDead)
   2033 	}
   2034 }
   2035 
   2036 // rangeIndexed emits to fn the header for an integer-indexed loop
   2037 // over array, *array or slice value x.
   2038 // The v result is defined only if tv is non-nil.
   2039 // forPos is the position of the "for" token.
   2040 func (b *builder) rangeIndexed(fn *Function, x Value, tv types.Type, pos token.Pos) (k, v Value, loop, done *BasicBlock) {
   2041 	//
   2042 	//     length = len(x)
   2043 	//     index = -1
   2044 	// loop:                                     (target of continue)
   2045 	//     index++
   2046 	//     if index < length goto body else done
   2047 	// body:
   2048 	//     k = index
   2049 	//     v = x[index]
   2050 	//     ...body...
   2051 	//     jump loop
   2052 	// done:                                     (target of break)
   2053 
   2054 	// Determine number of iterations.
   2055 	var length Value
   2056 	dt := typeparams.Deref(x.Type())
   2057 	if arr, ok := typeparams.CoreType(dt).(*types.Array); ok {
   2058 		// For array or *array, the number of iterations is
   2059 		// known statically thanks to the type.  We avoid a
   2060 		// data dependence upon x, permitting later dead-code
   2061 		// elimination if x is pure, static unrolling, etc.
   2062 		// Ranging over a nil *array may have >0 iterations.
   2063 		// We still generate code for x, in case it has effects.
   2064 		length = intConst(arr.Len())
   2065 	} else {
   2066 		// length = len(x).
   2067 		var c Call
   2068 		c.Call.Value = makeLen(x.Type())
   2069 		c.Call.Args = []Value{x}
   2070 		c.setType(tInt)
   2071 		length = fn.emit(&c)
   2072 	}
   2073 
   2074 	index := emitLocal(fn, tInt, token.NoPos, "rangeindex")
   2075 	emitStore(fn, index, intConst(-1), pos)
   2076 
   2077 	loop = fn.newBasicBlock("rangeindex.loop")
   2078 	emitJump(fn, loop)
   2079 	fn.currentBlock = loop
   2080 
   2081 	incr := &BinOp{
   2082 		Op: token.ADD,
   2083 		X:  emitLoad(fn, index),
   2084 		Y:  vOne,
   2085 	}
   2086 	incr.setType(tInt)
   2087 	emitStore(fn, index, fn.emit(incr), pos)
   2088 
   2089 	body := fn.newBasicBlock("rangeindex.body")
   2090 	done = fn.newBasicBlock("rangeindex.done")
   2091 	emitIf(fn, emitCompare(fn, token.LSS, incr, length, token.NoPos), body, done)
   2092 	fn.currentBlock = body
   2093 
   2094 	k = emitLoad(fn, index)
   2095 	if tv != nil {
   2096 		switch t := typeparams.CoreType(x.Type()).(type) {
   2097 		case *types.Array:
   2098 			instr := &Index{
   2099 				X:     x,
   2100 				Index: k,
   2101 			}
   2102 			instr.setType(t.Elem())
   2103 			instr.setPos(x.Pos())
   2104 			v = fn.emit(instr)
   2105 
   2106 		case *types.Pointer: // *array
   2107 			instr := &IndexAddr{
   2108 				X:     x,
   2109 				Index: k,
   2110 			}
   2111 			instr.setType(types.NewPointer(t.Elem().Underlying().(*types.Array).Elem()))
   2112 			instr.setPos(x.Pos())
   2113 			v = emitLoad(fn, fn.emit(instr))
   2114 
   2115 		case *types.Slice:
   2116 			instr := &IndexAddr{
   2117 				X:     x,
   2118 				Index: k,
   2119 			}
   2120 			instr.setType(types.NewPointer(t.Elem()))
   2121 			instr.setPos(x.Pos())
   2122 			v = emitLoad(fn, fn.emit(instr))
   2123 
   2124 		default:
   2125 			panic("rangeIndexed x:" + t.String())
   2126 		}
   2127 	}
   2128 	return
   2129 }
   2130 
   2131 // rangeIter emits to fn the header for a loop using
   2132 // Range/Next/Extract to iterate over map or string value x.
   2133 // tk and tv are the types of the key/value results k and v, or nil
   2134 // if the respective component is not wanted.
   2135 func (b *builder) rangeIter(fn *Function, x Value, tk, tv types.Type, pos token.Pos) (k, v Value, loop, done *BasicBlock) {
   2136 	//
   2137 	//     it = range x
   2138 	// loop:                                   (target of continue)
   2139 	//     okv = next it                       (ok, key, value)
   2140 	//     ok = extract okv #0
   2141 	//     if ok goto body else done
   2142 	// body:
   2143 	//     k = extract okv #1
   2144 	//     v = extract okv #2
   2145 	//     ...body...
   2146 	//     jump loop
   2147 	// done:                                   (target of break)
   2148 	//
   2149 
   2150 	rng := &Range{X: x}
   2151 	rng.setPos(pos)
   2152 	rng.setType(tRangeIter)
   2153 	it := fn.emit(rng)
   2154 
   2155 	loop = fn.newBasicBlock("rangeiter.loop")
   2156 	emitJump(fn, loop)
   2157 	fn.currentBlock = loop
   2158 
   2159 	var ak, av types.Type
   2160 	isString := false
   2161 	if m, ok := typeparams.CoreType(x.Type()).(*types.Map); ok {
   2162 		ak, av = m.Key(), m.Elem()
   2163 	} else {
   2164 		isString = true
   2165 		ak, av = tInt, tRune
   2166 	}
   2167 	if tk == nil {
   2168 		ak = tInvalid
   2169 	}
   2170 	if tv == nil {
   2171 		av = tInvalid
   2172 	}
   2173 
   2174 	okv := &Next{
   2175 		Iter:     it,
   2176 		IsString: isString,
   2177 	}
   2178 	okv.setType(types.NewTuple(
   2179 		varOk,
   2180 		newVar("k", ak),
   2181 		newVar("v", av),
   2182 	))
   2183 	fn.emit(okv)
   2184 
   2185 	body := fn.newBasicBlock("rangeiter.body")
   2186 	done = fn.newBasicBlock("rangeiter.done")
   2187 	emitIf(fn, emitExtract(fn, okv, 0), body, done)
   2188 	fn.currentBlock = body
   2189 
   2190 	// The assignment may widen a map or string
   2191 	// key/value to a variable's interface type
   2192 	// (cases #1 and #2 of go.dev/issue/78110).
   2193 	if tk != nil {
   2194 		k = emitConv(fn, emitExtract(fn, okv, 1), tk)
   2195 	}
   2196 	if tv != nil {
   2197 		v = emitConv(fn, emitExtract(fn, okv, 2), tv)
   2198 	}
   2199 	return
   2200 }
   2201 
   2202 // rangeChan emits to fn the header for a loop that receives from
   2203 // channel x until it fails.
   2204 // tk is the channel's element type, or nil if the k result is
   2205 // not wanted
   2206 // pos is the position of the '=' or ':=' token.
   2207 func (b *builder) rangeChan(fn *Function, x Value, tk types.Type, pos token.Pos) (k Value, loop, done *BasicBlock) {
   2208 	//
   2209 	// loop:                                   (target of continue)
   2210 	//     ko = <-x                            (key, ok)
   2211 	//     ok = extract ko #1
   2212 	//     if ok goto body else done
   2213 	// body:
   2214 	//     k = extract ko #0
   2215 	//     ...body...
   2216 	//     goto loop
   2217 	// done:                                   (target of break)
   2218 
   2219 	loop = fn.newBasicBlock("rangechan.loop")
   2220 	emitJump(fn, loop)
   2221 	fn.currentBlock = loop
   2222 	recv := &UnOp{
   2223 		Op:      token.ARROW,
   2224 		X:       x,
   2225 		CommaOk: true,
   2226 	}
   2227 	recv.setPos(pos)
   2228 	recv.setType(types.NewTuple(
   2229 		newVar("k", typeparams.CoreType(x.Type()).(*types.Chan).Elem()),
   2230 		varOk,
   2231 	))
   2232 	ko := fn.emit(recv)
   2233 	body := fn.newBasicBlock("rangechan.body")
   2234 	done = fn.newBasicBlock("rangechan.done")
   2235 	emitIf(fn, emitExtract(fn, ko, 1), body, done)
   2236 	fn.currentBlock = body
   2237 	if tk != nil {
   2238 		k = emitExtract(fn, ko, 0)
   2239 	}
   2240 	return
   2241 }
   2242 
   2243 // rangeInt emits to fn the header for a range loop with an integer operand.
   2244 // tk is the key value's type, or nil if the k result is not wanted.
   2245 // pos is the position of the "for" token.
   2246 func (b *builder) rangeInt(fn *Function, x Value, tk types.Type, pos token.Pos) (k Value, loop, done *BasicBlock) {
   2247 	//
   2248 	//     iter = 0
   2249 	//     if 0 < x goto body else done
   2250 	// loop:                                   (target of continue)
   2251 	//     iter++
   2252 	//     if iter < x goto body else done
   2253 	// body:
   2254 	//     k = x
   2255 	//     ...body...
   2256 	//     jump loop
   2257 	// done:                                   (target of break)
   2258 
   2259 	if isUntyped(x.Type()) {
   2260 		x = emitConv(fn, x, tInt)
   2261 	}
   2262 
   2263 	T := x.Type()
   2264 	iter := emitLocal(fn, T, token.NoPos, "rangeint.iter")
   2265 	// x may be unsigned. Avoid initializing x to -1.
   2266 
   2267 	body := fn.newBasicBlock("rangeint.body")
   2268 	done = fn.newBasicBlock("rangeint.done")
   2269 	emitIf(fn, emitCompare(fn, token.LSS, zeroConst(T), x, token.NoPos), body, done)
   2270 
   2271 	loop = fn.newBasicBlock("rangeint.loop")
   2272 	fn.currentBlock = loop
   2273 
   2274 	incr := &BinOp{
   2275 		Op: token.ADD,
   2276 		X:  emitLoad(fn, iter),
   2277 		Y:  emitConv(fn, vOne, T),
   2278 	}
   2279 	incr.setType(T)
   2280 	emitStore(fn, iter, fn.emit(incr), pos)
   2281 	emitIf(fn, emitCompare(fn, token.LSS, incr, x, token.NoPos), body, done)
   2282 	fn.currentBlock = body
   2283 
   2284 	if tk != nil {
   2285 		// Integer types (int, uint8, etc.) are named and
   2286 		// we know that k is assignable to x when tk != nil.
   2287 		// This implies tk and T are identical so no conversion is needed.
   2288 		k = emitLoad(fn, iter)
   2289 	}
   2290 
   2291 	return
   2292 }
   2293 
   2294 // rangeStmt emits to fn code for the range statement s, optionally
   2295 // labelled by label.
   2296 func (b *builder) rangeStmt(fn *Function, s *ast.RangeStmt, label *lblock) {
   2297 	var tk, tv types.Type
   2298 	if s.Key != nil && !isBlankIdent(s.Key) {
   2299 		tk = fn.typeOf(s.Key)
   2300 	}
   2301 	if s.Value != nil && !isBlankIdent(s.Value) {
   2302 		tv = fn.typeOf(s.Value)
   2303 	}
   2304 
   2305 	// create locals for s.Key and s.Value.
   2306 	createVars := func() {
   2307 		// Unlike a short variable declaration, a RangeStmt
   2308 		// using := never redeclares an existing variable; it
   2309 		// always creates a new one.
   2310 		if tk != nil {
   2311 			emitLocalVar(fn, identVar(fn, s.Key.(*ast.Ident)))
   2312 		}
   2313 		if tv != nil {
   2314 			emitLocalVar(fn, identVar(fn, s.Value.(*ast.Ident)))
   2315 		}
   2316 	}
   2317 
   2318 	afterGo122 := versions.AtLeast(fn.goversion, versions.Go1_22)
   2319 	if s.Tok == token.DEFINE && !afterGo122 {
   2320 		// pre-go1.22: If iteration variables are defined (:=), this
   2321 		// occurs once outside the loop.
   2322 		createVars()
   2323 	}
   2324 
   2325 	x := b.expr(fn, s.X)
   2326 
   2327 	var k, v Value
   2328 	var loop, done *BasicBlock
   2329 	switch rt := typeparams.CoreType(x.Type()).(type) {
   2330 	case *types.Slice, *types.Array, *types.Pointer: // *array
   2331 		k, v, loop, done = b.rangeIndexed(fn, x, tv, s.For)
   2332 
   2333 	case *types.Chan:
   2334 		k, loop, done = b.rangeChan(fn, x, tk, s.For)
   2335 
   2336 	case *types.Map:
   2337 		k, v, loop, done = b.rangeIter(fn, x, tk, tv, s.For)
   2338 
   2339 	case *types.Basic:
   2340 		switch {
   2341 		case rt.Info()&types.IsString != 0:
   2342 			k, v, loop, done = b.rangeIter(fn, x, tk, tv, s.For)
   2343 
   2344 		case rt.Info()&types.IsInteger != 0:
   2345 			k, loop, done = b.rangeInt(fn, x, tk, s.For)
   2346 
   2347 		default:
   2348 			panic("Cannot range over basic type: " + rt.String())
   2349 		}
   2350 
   2351 	case *types.Signature:
   2352 		// Special case rewrite (fn.goversion >= go1.23):
   2353 		// 	for x := range f { ... }
   2354 		// into
   2355 		// 	f(func(x T) bool { ... })
   2356 		b.rangeFunc(fn, x, s, label)
   2357 		return
   2358 
   2359 	default:
   2360 		panic("Cannot range over: " + rt.String())
   2361 	}
   2362 
   2363 	if s.Tok == token.DEFINE && afterGo122 {
   2364 		// go1.22: If iteration variables are defined (:=), this occurs inside the loop.
   2365 		createVars()
   2366 	}
   2367 
   2368 	// Evaluate both LHS expressions before we update either.
   2369 	var kl, vl lvalue
   2370 	if tk != nil {
   2371 		kl = b.addr(fn, s.Key, false) // non-escaping
   2372 	}
   2373 	if tv != nil {
   2374 		vl = b.addr(fn, s.Value, false) // non-escaping
   2375 	}
   2376 	if tk != nil {
   2377 		kl.store(fn, k)
   2378 	}
   2379 	if tv != nil {
   2380 		vl.store(fn, v)
   2381 	}
   2382 
   2383 	if label != nil {
   2384 		label._break = done
   2385 		label._continue = loop
   2386 	}
   2387 
   2388 	fn.targets = &targets{
   2389 		tail:      fn.targets,
   2390 		_break:    done,
   2391 		_continue: loop,
   2392 	}
   2393 	b.stmt(fn, s.Body)
   2394 	fn.targets = fn.targets.tail
   2395 	emitJump(fn, loop) // back-edge
   2396 	fn.currentBlock = done
   2397 }
   2398 
   2399 // rangeFunc emits to fn code for the range-over-func rng.Body of the iterator
   2400 // function x, optionally labelled by label. It creates a new anonymous function
   2401 // yield for rng and builds the function.
   2402 func (b *builder) rangeFunc(fn *Function, x Value, rng *ast.RangeStmt, label *lblock) {
   2403 	// Consider the SSA code for the outermost range-over-func in fn:
   2404 	//
   2405 	//   func fn(...) (ret R) {
   2406 	//     ...
   2407 	//     for k, v = range x {
   2408 	// 	     ...
   2409 	//     }
   2410 	//     ...
   2411 	//   }
   2412 	//
   2413 	// The code emitted into fn will look something like this.
   2414 	//
   2415 	// loop:
   2416 	//     jump := READY
   2417 	//     y := make closure yield [ret, deferstack, jump, k, v]
   2418 	//     x(y)
   2419 	//     switch jump {
   2420 	//        [see resuming execution]
   2421 	//     }
   2422 	//     goto done
   2423 	// done:
   2424 	//     ...
   2425 	//
   2426 	// where yield is a new synthetic yield function:
   2427 	//
   2428 	// func yield(_k tk, _v tv) bool
   2429 	//   free variables: [ret, stack, jump, k, v]
   2430 	// {
   2431 	//    entry:
   2432 	//      if jump != READY then goto invalid else valid
   2433 	//    invalid:
   2434 	//      panic("iterator called when it is not in a ready state")
   2435 	//    valid:
   2436 	//      jump = BUSY
   2437 	//      k = _k
   2438 	//      v = _v
   2439 	//    ...
   2440 	//    cont:
   2441 	//      jump = READY
   2442 	//      return true
   2443 	// }
   2444 	//
   2445 	// Yield state:
   2446 	//
   2447 	// Each range loop has an associated jump variable that records
   2448 	// the state of the iterator. A yield function is initially
   2449 	// in a READY (0) and callable state.  If the yield function is called
   2450 	// and is not in READY state, it panics. When it is called in a callable
   2451 	// state, it becomes BUSY. When execution reaches the end of the body
   2452 	// of the loop (or a continue statement targeting the loop is executed),
   2453 	// the yield function returns true and resumes being in a READY state.
   2454 	// After the iterator function x(y) returns, then if the yield function
   2455 	// is in a READY state, the yield enters the DONE state.
   2456 	//
   2457 	// Each lowered control statement (break X, continue X, goto Z, or return)
   2458 	// that exits the loop sets the variable to a unique positive EXIT value,
   2459 	// before returning false from the yield function.
   2460 	//
   2461 	// If the yield function returns abruptly due to a panic or GoExit,
   2462 	// it remains in a BUSY state. The generated code asserts that, after
   2463 	// the iterator call x(y) returns normally, the jump variable state
   2464 	// is DONE.
   2465 	//
   2466 	// Resuming execution:
   2467 	//
   2468 	// The code generated for the range statement checks the jump
   2469 	// variable to determine how to resume execution.
   2470 	//
   2471 	//    switch jump {
   2472 	//    case BUSY:  panic("...")
   2473 	//    case DONE:  goto done
   2474 	//    case READY: state = DONE; goto done
   2475 	//    case 123:   ... // action for exit 123.
   2476 	//    case 456:   ... // action for exit 456.
   2477 	//    ...
   2478 	//    }
   2479 	//
   2480 	// Forward goto statements within a yield are jumps to labels that
   2481 	// have not yet been traversed in fn. They may be in the Body of the
   2482 	// function. What we emit for these is:
   2483 	//
   2484 	//    goto target
   2485 	//  target:
   2486 	//    ...
   2487 	//
   2488 	// We leave an unresolved exit in yield.exits to check at the end
   2489 	// of building yield if it encountered target in the body. If it
   2490 	// encountered target, no additional work is required. Otherwise,
   2491 	// the yield emits a new early exit in the basic block for target.
   2492 	// We expect that blockopt will fuse the early exit into the case
   2493 	// block later. The unresolved exit is then added to yield.parent.exits.
   2494 
   2495 	loop := fn.newBasicBlock("rangefunc.loop")
   2496 	done := fn.newBasicBlock("rangefunc.done")
   2497 
   2498 	// These are targets within y.
   2499 	fn.targets = &targets{
   2500 		tail:   fn.targets,
   2501 		_break: done,
   2502 		// _continue is within y.
   2503 	}
   2504 	if label != nil {
   2505 		label._break = done
   2506 		// _continue is within y
   2507 	}
   2508 
   2509 	emitJump(fn, loop)
   2510 	fn.currentBlock = loop
   2511 
   2512 	// loop:
   2513 	//     jump := READY
   2514 
   2515 	anonIdx := len(fn.AnonFuncs)
   2516 
   2517 	jump := newVar(fmt.Sprintf("jump$%d", anonIdx+1), tInt)
   2518 	emitLocalVar(fn, jump) // zero value is READY
   2519 
   2520 	xsig := typeparams.CoreType(x.Type()).(*types.Signature)
   2521 	ysig := typeparams.CoreType(xsig.Params().At(0).Type()).(*types.Signature)
   2522 
   2523 	/* synthetic yield function for body of range-over-func loop */
   2524 	y := &Function{
   2525 		name:           fmt.Sprintf("%s$%d", fn.Name(), anonIdx+1),
   2526 		Signature:      ysig,
   2527 		Synthetic:      "range-over-func yield",
   2528 		pos:            rng.Range,
   2529 		parent:         fn,
   2530 		anonIdx:        int32(len(fn.AnonFuncs)),
   2531 		Pkg:            fn.Pkg,
   2532 		Prog:           fn.Prog,
   2533 		syntax:         rng,
   2534 		info:           fn.info,
   2535 		goversion:      fn.goversion,
   2536 		build:          (*builder).buildYieldFunc,
   2537 		topLevelOrigin: nil,
   2538 		typeparams:     fn.typeparams,
   2539 		typeargs:       fn.typeargs,
   2540 		subst:          fn.subst,
   2541 		jump:           jump,
   2542 		deferstack:     fn.deferstack,
   2543 		returnVars:     fn.returnVars, // use the parent's return variables
   2544 		uniq:           fn.uniq,       // start from parent's unique values
   2545 	}
   2546 
   2547 	// If the RangeStmt has a label, this is how it is passed to buildYieldFunc.
   2548 	if label != nil {
   2549 		y.lblocks = map[*types.Label]*lblock{label.label: nil}
   2550 	}
   2551 	fn.AnonFuncs = append(fn.AnonFuncs, y)
   2552 
   2553 	// Build y immediately. It may:
   2554 	// * cause fn's locals to escape, and
   2555 	// * create new exit nodes in exits.
   2556 	// (y is not marked 'built' until the end of the enclosing FuncDecl.)
   2557 	unresolved := len(fn.exits)
   2558 	y.build(b, y)
   2559 	fn.uniq = y.uniq // resume after y's unique values
   2560 
   2561 	// Emit the call of y.
   2562 	//   c := MakeClosure y
   2563 	//   x(c)
   2564 	c := &MakeClosure{Fn: y}
   2565 	c.setType(ysig)
   2566 	for _, fv := range y.FreeVars {
   2567 		c.Bindings = append(c.Bindings, fv.outer)
   2568 		fv.outer = nil
   2569 	}
   2570 	fn.emit(c)
   2571 	call := Call{
   2572 		Call: CallCommon{
   2573 			Value: x,
   2574 			Args:  []Value{c},
   2575 			pos:   token.NoPos,
   2576 		},
   2577 	}
   2578 	call.setType(xsig.Results())
   2579 	fn.emit(&call)
   2580 
   2581 	exits := fn.exits[unresolved:]
   2582 	b.buildYieldResume(fn, jump, exits, done)
   2583 
   2584 	emitJump(fn, done)
   2585 	fn.currentBlock = done
   2586 	// pop the stack for the range-over-func
   2587 	fn.targets = fn.targets.tail
   2588 }
   2589 
   2590 // buildYieldResume emits to fn code for how to resume execution once a call to
   2591 // the iterator function over the yield function returns x(y). It does this by building
   2592 // a switch over the value of jump for when it is READY, BUSY, or EXIT(id).
   2593 func (b *builder) buildYieldResume(fn *Function, jump *types.Var, exits []*exit, done *BasicBlock) {
   2594 	//    v := *jump
   2595 	//    switch v {
   2596 	//    case BUSY:    panic("...")
   2597 	//    case READY:   jump = DONE; goto done
   2598 	//    case EXIT(a): ...
   2599 	//    case EXIT(b): ...
   2600 	//    ...
   2601 	//    }
   2602 	v := emitLoad(fn, fn.lookup(jump, false))
   2603 
   2604 	// case BUSY: panic("...")
   2605 	isbusy := fn.newBasicBlock("rangefunc.resume.busy")
   2606 	ifready := fn.newBasicBlock("rangefunc.resume.ready.check")
   2607 	emitIf(fn, emitCompare(fn, token.EQL, v, jBusy, token.NoPos), isbusy, ifready)
   2608 	fn.currentBlock = isbusy
   2609 	fn.emit(&Panic{
   2610 		X: emitConv(fn, stringConst("iterator call did not preserve panic"), tEface),
   2611 	})
   2612 	fn.currentBlock = ifready
   2613 
   2614 	// case READY: jump = DONE; goto done
   2615 	isready := fn.newBasicBlock("rangefunc.resume.ready")
   2616 	ifexit := fn.newBasicBlock("rangefunc.resume.exits")
   2617 	emitIf(fn, emitCompare(fn, token.EQL, v, jReady, token.NoPos), isready, ifexit)
   2618 	fn.currentBlock = isready
   2619 	storeVar(fn, jump, jDone, token.NoPos)
   2620 	emitJump(fn, done)
   2621 	fn.currentBlock = ifexit
   2622 
   2623 	for _, e := range exits {
   2624 		id := intConst(e.id)
   2625 
   2626 		//  case EXIT(id): { /* do e */ }
   2627 		cond := emitCompare(fn, token.EQL, v, id, e.pos)
   2628 		matchb := fn.newBasicBlock("rangefunc.resume.match")
   2629 		cndb := fn.newBasicBlock("rangefunc.resume.cnd")
   2630 		emitIf(fn, cond, matchb, cndb)
   2631 		fn.currentBlock = matchb
   2632 
   2633 		// Cases to fill in the { /* do e */ } bit.
   2634 		switch {
   2635 		case e.label != nil: // forward goto?
   2636 			// case EXIT(id): goto lb // label
   2637 			lb := fn.lblockOf(e.label)
   2638 			// Do not mark lb as resolved.
   2639 			// If fn does not contain label, lb remains unresolved and
   2640 			// fn must itself be a range-over-func function. lb will be:
   2641 			//   lb:
   2642 			//     fn.jump = id
   2643 			//     return false
   2644 			emitJump(fn, lb._goto)
   2645 
   2646 		case e.to != fn: // e jumps to an ancestor of fn?
   2647 			// case EXIT(id): { fn.jump = id; return false }
   2648 			// fn is a range-over-func function.
   2649 			storeVar(fn, fn.jump, id, token.NoPos)
   2650 			fn.emit(&Return{Results: []Value{vFalse}, pos: e.pos})
   2651 
   2652 		case e.block == nil && e.label == nil: // return from fn?
   2653 			// case EXIT(id): { return ... }
   2654 			fn.emit(new(RunDefers))
   2655 			results := make([]Value, len(fn.results))
   2656 			for i, r := range fn.results {
   2657 				results[i] = emitLoad(fn, r)
   2658 			}
   2659 			fn.emit(&Return{Results: results, pos: e.pos})
   2660 
   2661 		case e.block != nil:
   2662 			// case EXIT(id): goto block
   2663 			emitJump(fn, e.block)
   2664 
   2665 		default:
   2666 			panic("unreachable")
   2667 		}
   2668 		fn.currentBlock = cndb
   2669 	}
   2670 }
   2671 
   2672 // stmt lowers statement s to SSA form, emitting code to fn.
   2673 func (b *builder) stmt(fn *Function, _s ast.Stmt) {
   2674 	// The label of the current statement.  If non-nil, its _goto
   2675 	// target is always set; its _break and _continue are set only
   2676 	// within the body of switch/typeswitch/select/for/range.
   2677 	// It is effectively an additional default-nil parameter of stmt().
   2678 	var label *lblock
   2679 start:
   2680 	switch s := _s.(type) {
   2681 	case *ast.EmptyStmt:
   2682 		// ignore.  (Usually removed by gofmt.)
   2683 
   2684 	case *ast.DeclStmt: // Con, Var or Typ
   2685 		d := s.Decl.(*ast.GenDecl)
   2686 		if d.Tok == token.VAR {
   2687 			for _, spec := range d.Specs {
   2688 				if vs, ok := spec.(*ast.ValueSpec); ok {
   2689 					b.localValueSpec(fn, vs)
   2690 				}
   2691 			}
   2692 		}
   2693 
   2694 	case *ast.LabeledStmt:
   2695 		if s.Label.Name == "_" {
   2696 			// Blank labels can't be the target of a goto, break,
   2697 			// or continue statement, so we don't need a new block.
   2698 			_s = s.Stmt
   2699 			goto start
   2700 		}
   2701 		label = fn.lblockOf(fn.label(s.Label))
   2702 		label.resolved = true
   2703 		emitJump(fn, label._goto)
   2704 		fn.currentBlock = label._goto
   2705 		_s = s.Stmt
   2706 		goto start // effectively: tailcall stmt(fn, s.Stmt, label)
   2707 
   2708 	case *ast.ExprStmt:
   2709 		b.expr(fn, s.X)
   2710 
   2711 	case *ast.SendStmt:
   2712 		chtyp := typeparams.CoreType(fn.typeOf(s.Chan)).(*types.Chan)
   2713 		fn.emit(&Send{
   2714 			Chan: b.expr(fn, s.Chan),
   2715 			X:    emitConv(fn, b.expr(fn, s.Value), chtyp.Elem()),
   2716 			pos:  s.Arrow,
   2717 		})
   2718 
   2719 	case *ast.IncDecStmt:
   2720 		op := token.ADD
   2721 		if s.Tok == token.DEC {
   2722 			op = token.SUB
   2723 		}
   2724 		loc := b.addr(fn, s.X, false)
   2725 		b.assignOp(fn, loc, NewConst(constant.MakeInt64(1), loc.typ()), op, s.Pos())
   2726 
   2727 	case *ast.AssignStmt:
   2728 		switch s.Tok {
   2729 		case token.ASSIGN, token.DEFINE:
   2730 			b.assignStmt(fn, s.Lhs, s.Rhs, s.Tok == token.DEFINE)
   2731 
   2732 		default: // +=, etc.
   2733 			op := s.Tok + token.ADD - token.ADD_ASSIGN
   2734 			b.assignOp(fn, b.addr(fn, s.Lhs[0], false), b.expr(fn, s.Rhs[0]), op, s.Pos())
   2735 		}
   2736 
   2737 	case *ast.GoStmt:
   2738 		// The "intrinsics" new/make/len/cap are forbidden here.
   2739 		// panic is treated like an ordinary function call.
   2740 		v := Go{pos: s.Go}
   2741 		b.setCall(fn, s.Call, &v.Call)
   2742 		fn.emit(&v)
   2743 
   2744 	case *ast.DeferStmt:
   2745 		// The "intrinsics" new/make/len/cap are forbidden here.
   2746 		// panic is treated like an ordinary function call.
   2747 		deferstack := emitLoad(fn, fn.lookup(fn.deferstack, false))
   2748 		v := Defer{pos: s.Defer, DeferStack: deferstack}
   2749 		b.setCall(fn, s.Call, &v.Call)
   2750 		fn.emit(&v)
   2751 
   2752 		// A deferred call can cause recovery from panic,
   2753 		// and control resumes at the Recover block.
   2754 		createRecoverBlock(fn.source)
   2755 
   2756 	case *ast.ReturnStmt:
   2757 		b.returnStmt(fn, s)
   2758 
   2759 	case *ast.BranchStmt:
   2760 		b.branchStmt(fn, s)
   2761 
   2762 	case *ast.BlockStmt:
   2763 		b.stmtList(fn, s.List)
   2764 
   2765 	case *ast.IfStmt:
   2766 		if s.Init != nil {
   2767 			b.stmt(fn, s.Init)
   2768 		}
   2769 		then := fn.newBasicBlock("if.then")
   2770 		done := fn.newBasicBlock("if.done")
   2771 		els := done
   2772 		if s.Else != nil {
   2773 			els = fn.newBasicBlock("if.else")
   2774 		}
   2775 		b.cond(fn, s.Cond, then, els)
   2776 		fn.currentBlock = then
   2777 		b.stmt(fn, s.Body)
   2778 		emitJump(fn, done)
   2779 
   2780 		if s.Else != nil {
   2781 			fn.currentBlock = els
   2782 			b.stmt(fn, s.Else)
   2783 			emitJump(fn, done)
   2784 		}
   2785 
   2786 		fn.currentBlock = done
   2787 
   2788 	case *ast.SwitchStmt:
   2789 		b.switchStmt(fn, s, label)
   2790 
   2791 	case *ast.TypeSwitchStmt:
   2792 		b.typeSwitchStmt(fn, s, label)
   2793 
   2794 	case *ast.SelectStmt:
   2795 		b.selectStmt(fn, s, label)
   2796 
   2797 	case *ast.ForStmt:
   2798 		b.forStmt(fn, s, label)
   2799 
   2800 	case *ast.RangeStmt:
   2801 		b.rangeStmt(fn, s, label)
   2802 
   2803 	default:
   2804 		panic(fmt.Sprintf("unexpected statement kind: %T", s))
   2805 	}
   2806 }
   2807 
   2808 func (b *builder) branchStmt(fn *Function, s *ast.BranchStmt) {
   2809 	var block *BasicBlock
   2810 	if s.Label == nil {
   2811 		block = targetedBlock(fn, s.Tok)
   2812 	} else {
   2813 		target := fn.label(s.Label)
   2814 		block = labelledBlock(fn, target, s.Tok)
   2815 		if block == nil { // forward goto
   2816 			lb := fn.lblockOf(target)
   2817 			block = lb._goto // jump to lb._goto
   2818 			if fn.jump != nil {
   2819 				// fn is a range-over-func and the goto may exit fn.
   2820 				// Create an exit and resolve it at the end of
   2821 				// builder.buildYieldFunc.
   2822 				labelExit(fn, target, s.Pos())
   2823 			}
   2824 		}
   2825 	}
   2826 	to := block.parent
   2827 
   2828 	if to == fn {
   2829 		emitJump(fn, block)
   2830 	} else { // break outside of fn.
   2831 		// fn must be a range-over-func
   2832 		e := blockExit(fn, block, s.Pos())
   2833 		storeVar(fn, fn.jump, intConst(e.id), e.pos)
   2834 		fn.emit(&Return{Results: []Value{vFalse}, pos: e.pos})
   2835 	}
   2836 	fn.currentBlock = fn.newBasicBlock("unreachable")
   2837 }
   2838 
   2839 func (b *builder) returnStmt(fn *Function, s *ast.ReturnStmt) {
   2840 	var results []Value
   2841 
   2842 	sig := fn.source.Signature // signature of the enclosing source function
   2843 
   2844 	// Convert return operands to result type.
   2845 	if len(s.Results) == 1 && sig.Results().Len() > 1 {
   2846 		// Return of one expression in a multi-valued function.
   2847 		tuple := b.exprN(fn, s.Results[0])
   2848 		ttuple := tuple.Type().(*types.Tuple)
   2849 		for i, n := 0, ttuple.Len(); i < n; i++ {
   2850 			results = append(results,
   2851 				emitConv(fn, emitExtract(fn, tuple, i),
   2852 					sig.Results().At(i).Type()))
   2853 		}
   2854 	} else {
   2855 		// 1:1 return, or no-arg return in non-void function.
   2856 		for i, r := range s.Results {
   2857 			v := emitConv(fn, b.expr(fn, r), sig.Results().At(i).Type())
   2858 			results = append(results, v)
   2859 		}
   2860 	}
   2861 
   2862 	// Store the results.
   2863 	for i, r := range results {
   2864 		var result Value // fn.source.result[i] conceptually
   2865 		if fn == fn.source {
   2866 			result = fn.results[i]
   2867 		} else { // lookup needed?
   2868 			result = fn.lookup(fn.returnVars[i], false)
   2869 		}
   2870 		emitStore(fn, result, r, s.Return)
   2871 	}
   2872 
   2873 	if fn.jump != nil {
   2874 		// Return from body of a range-over-func.
   2875 		// The return statement is syntactically within the loop,
   2876 		// but the generated code is in the 'switch jump {...}' after it.
   2877 		e := returnExit(fn, s.Pos())
   2878 		storeVar(fn, fn.jump, intConst(e.id), e.pos)
   2879 		fn.emit(&Return{Results: []Value{vFalse}, pos: e.pos})
   2880 		fn.currentBlock = fn.newBasicBlock("unreachable")
   2881 		return
   2882 	}
   2883 
   2884 	// Run function calls deferred in this
   2885 	// function when explicitly returning from it.
   2886 	fn.emit(new(RunDefers))
   2887 	// Reload (potentially) named result variables to form the result tuple.
   2888 	results = results[:0]
   2889 	for _, nr := range fn.results {
   2890 		results = append(results, emitLoad(fn, nr))
   2891 	}
   2892 	fn.emit(&Return{Results: results, pos: s.Return})
   2893 	fn.currentBlock = fn.newBasicBlock("unreachable")
   2894 }
   2895 
   2896 // A buildFunc is a strategy for building the SSA body for a function.
   2897 type buildFunc = func(*builder, *Function)
   2898 
   2899 // iterate causes all created but unbuilt functions to be built. As
   2900 // this may create new methods, the process is iterated until it
   2901 // converges.
   2902 //
   2903 // Waits for any dependencies to finish building.
   2904 func (b *builder) iterate() {
   2905 	for ; b.finished < len(b.fns); b.finished++ {
   2906 		fn := b.fns[b.finished]
   2907 		b.buildFunction(fn)
   2908 	}
   2909 
   2910 	b.buildshared.markDone()
   2911 	b.buildshared.wait()
   2912 }
   2913 
   2914 // buildFunction builds SSA code for the body of function fn.  Idempotent.
   2915 func (b *builder) buildFunction(fn *Function) {
   2916 	if fn.build != nil {
   2917 		assert(fn.parent == nil, "anonymous functions should not be built by buildFunction()")
   2918 
   2919 		if fn.Prog.mode&LogSource != 0 {
   2920 			defer logStack("build %s @ %s", fn, fn.Prog.Fset.Position(fn.pos))()
   2921 		}
   2922 		fn.build(b, fn)
   2923 		fn.done()
   2924 	}
   2925 }
   2926 
   2927 // buildParamsOnly builds fn.Params from fn.Signature, but does not build fn.Body.
   2928 func (b *builder) buildParamsOnly(fn *Function) {
   2929 	// For external (C, asm) functions or functions loaded from
   2930 	// export data, we must set fn.Params even though there is no
   2931 	// body code to reference them.
   2932 	if recv := fn.Signature.Recv(); recv != nil {
   2933 		fn.addParamVar(recv)
   2934 	}
   2935 	params := fn.Signature.Params()
   2936 	for i, n := 0, params.Len(); i < n; i++ {
   2937 		fn.addParamVar(params.At(i))
   2938 	}
   2939 
   2940 	// clear out other function state (keep consistent with finishBody)
   2941 	fn.subst = nil
   2942 }
   2943 
   2944 // buildFromSyntax builds fn.Body from fn.syntax, which must be non-nil.
   2945 func (b *builder) buildFromSyntax(fn *Function) {
   2946 	var (
   2947 		recvField *ast.FieldList
   2948 		body      *ast.BlockStmt
   2949 		functype  *ast.FuncType
   2950 	)
   2951 	switch syntax := fn.syntax.(type) {
   2952 	case *ast.FuncDecl:
   2953 		functype = syntax.Type
   2954 		recvField = syntax.Recv
   2955 		body = syntax.Body
   2956 		if body == nil {
   2957 			b.buildParamsOnly(fn) // no body (non-Go function)
   2958 			return
   2959 		}
   2960 	case *ast.FuncLit:
   2961 		functype = syntax.Type
   2962 		body = syntax.Body
   2963 	case nil:
   2964 		panic("no syntax")
   2965 	default:
   2966 		panic(syntax) // unexpected syntax
   2967 	}
   2968 	fn.source = fn
   2969 	fn.startBody()
   2970 	fn.createSyntacticParams(recvField, functype)
   2971 	fn.createDeferStack()
   2972 	b.stmt(fn, body)
   2973 	if cb := fn.currentBlock; cb != nil && (cb == fn.Blocks[0] || cb == fn.Recover || cb.Preds != nil) {
   2974 		// Control fell off the end of the function's body block.
   2975 		//
   2976 		// Block optimizations eliminate the current block, if
   2977 		// unreachable.  It is a builder invariant that
   2978 		// if this no-arg return is ill-typed for
   2979 		// fn.Signature.Results, this block must be
   2980 		// unreachable.  The sanity checker checks this.
   2981 		fn.emit(new(RunDefers))
   2982 		fn.emit(new(Return))
   2983 	}
   2984 	fn.finishBody()
   2985 }
   2986 
   2987 // buildYieldFunc builds the body of the yield function created
   2988 // from a range-over-func *ast.RangeStmt.
   2989 func (b *builder) buildYieldFunc(fn *Function) {
   2990 	// See builder.rangeFunc for detailed documentation on how fn is set up.
   2991 	//
   2992 	// In pseudo-Go this roughly builds:
   2993 	// func yield(_k tk, _v tv) bool {
   2994 	// 	   if jump != READY { panic("yield function called after range loop exit") }
   2995 	//     jump = BUSY
   2996 	//     k, v = _k, _v // assign the iterator variable (if needed)
   2997 	//     ... // rng.Body
   2998 	//   continue:
   2999 	//     jump = READY
   3000 	//     return true
   3001 	// }
   3002 	s := fn.syntax.(*ast.RangeStmt)
   3003 	fn.source = fn.parent.source
   3004 	fn.startBody()
   3005 	params := fn.Signature.Params()
   3006 	for v := range params.Variables() {
   3007 		fn.addParamVar(v)
   3008 	}
   3009 
   3010 	// Initial targets
   3011 	ycont := fn.newBasicBlock("yield-continue")
   3012 	// lblocks is either {} or is {label: nil} where label is the label of syntax.
   3013 	for label := range fn.lblocks {
   3014 		fn.lblocks[label] = &lblock{
   3015 			label:     label,
   3016 			resolved:  true,
   3017 			_goto:     ycont,
   3018 			_continue: ycont,
   3019 			// `break label` statement targets fn.parent.targets._break
   3020 		}
   3021 	}
   3022 	fn.targets = &targets{
   3023 		tail:      fn.targets,
   3024 		_continue: ycont,
   3025 		// `break` statement targets fn.parent.targets._break.
   3026 	}
   3027 
   3028 	// continue:
   3029 	//   jump = READY
   3030 	//   return true
   3031 	saved := fn.currentBlock
   3032 	fn.currentBlock = ycont
   3033 	storeVar(fn, fn.jump, jReady, s.Body.Rbrace)
   3034 	// A yield function's own deferstack is always empty, so rundefers is not needed.
   3035 	fn.emit(&Return{Results: []Value{vTrue}, pos: token.NoPos})
   3036 
   3037 	// Emit header:
   3038 	//
   3039 	//   if jump != READY { panic("yield iterator accessed after exit") }
   3040 	//   jump = BUSY
   3041 	//   k, v = _k, _v
   3042 	fn.currentBlock = saved
   3043 	yloop := fn.newBasicBlock("yield-loop")
   3044 	invalid := fn.newBasicBlock("yield-invalid")
   3045 
   3046 	jumpVal := emitLoad(fn, fn.lookup(fn.jump, true))
   3047 	emitIf(fn, emitCompare(fn, token.EQL, jumpVal, jReady, token.NoPos), yloop, invalid)
   3048 	fn.currentBlock = invalid
   3049 	fn.emit(&Panic{
   3050 		X: emitConv(fn, stringConst("yield function called after range loop exit"), tEface),
   3051 	})
   3052 
   3053 	fn.currentBlock = yloop
   3054 	storeVar(fn, fn.jump, jBusy, s.Body.Rbrace)
   3055 
   3056 	// Initialize k and v from params.
   3057 	var tk, tv types.Type
   3058 	if s.Key != nil && !isBlankIdent(s.Key) {
   3059 		tk = fn.typeOf(s.Key) // fn.parent.typeOf is identical
   3060 	}
   3061 	if s.Value != nil && !isBlankIdent(s.Value) {
   3062 		tv = fn.typeOf(s.Value)
   3063 	}
   3064 	if s.Tok == token.DEFINE {
   3065 		if tk != nil {
   3066 			emitLocalVar(fn, identVar(fn, s.Key.(*ast.Ident)))
   3067 		}
   3068 		if tv != nil {
   3069 			emitLocalVar(fn, identVar(fn, s.Value.(*ast.Ident)))
   3070 		}
   3071 	}
   3072 	var k, v Value
   3073 	if len(fn.Params) > 0 {
   3074 		k = fn.Params[0]
   3075 	}
   3076 	if len(fn.Params) > 1 {
   3077 		v = fn.Params[1]
   3078 	}
   3079 	var kl, vl lvalue
   3080 	if tk != nil {
   3081 		kl = b.addr(fn, s.Key, false) // non-escaping
   3082 	}
   3083 	if tv != nil {
   3084 		vl = b.addr(fn, s.Value, false) // non-escaping
   3085 	}
   3086 	if tk != nil {
   3087 		kl.store(fn, k)
   3088 	}
   3089 	if tv != nil {
   3090 		vl.store(fn, v)
   3091 	}
   3092 
   3093 	// Build the body of the range loop.
   3094 	b.stmt(fn, s.Body)
   3095 	if cb := fn.currentBlock; cb != nil && (cb == fn.Blocks[0] || cb == fn.Recover || cb.Preds != nil) {
   3096 		// Control fell off the end of the function's body block.
   3097 		// Block optimizations eliminate the current block, if
   3098 		// unreachable.
   3099 		emitJump(fn, ycont)
   3100 	}
   3101 	// pop the stack for the yield function
   3102 	fn.targets = fn.targets.tail
   3103 
   3104 	// Clean up exits and promote any unresolved exits to fn.parent.
   3105 	for _, e := range fn.exits {
   3106 		if e.label != nil {
   3107 			lb := fn.lblocks[e.label]
   3108 			if lb.resolved {
   3109 				// label was resolved. Do not turn lb into an exit.
   3110 				// e does not need to be handled by the parent.
   3111 				continue
   3112 			}
   3113 
   3114 			// _goto becomes an exit.
   3115 			//   _goto:
   3116 			//     jump = id
   3117 			//     return false
   3118 			fn.currentBlock = lb._goto
   3119 			id := intConst(e.id)
   3120 			storeVar(fn, fn.jump, id, e.pos)
   3121 			fn.emit(&Return{Results: []Value{vFalse}, pos: e.pos})
   3122 		}
   3123 
   3124 		if e.to != fn { // e needs to be handled by the parent too.
   3125 			fn.parent.exits = append(fn.parent.exits, e)
   3126 		}
   3127 	}
   3128 
   3129 	fn.finishBody()
   3130 }
   3131 
   3132 // addMakeInterfaceType records non-interface type t as the type of
   3133 // the operand a MakeInterface operation, for [Program.RuntimeTypes].
   3134 //
   3135 // Acquires prog.makeInterfaceTypesMu.
   3136 func addMakeInterfaceType(prog *Program, t types.Type) {
   3137 	prog.makeInterfaceTypesMu.Lock()
   3138 	defer prog.makeInterfaceTypesMu.Unlock()
   3139 	if prog.makeInterfaceTypes == nil {
   3140 		prog.makeInterfaceTypes = make(map[types.Type]unit)
   3141 	}
   3142 	prog.makeInterfaceTypes[t] = unit{}
   3143 }
   3144 
   3145 // Build calls Package.Build for each package in prog.
   3146 // Building occurs in parallel unless the BuildSerially mode flag was set.
   3147 //
   3148 // Build is intended for whole-program analysis; a typical compiler
   3149 // need only build a single package.
   3150 //
   3151 // Build is idempotent and thread-safe.
   3152 func (prog *Program) Build() {
   3153 	var wg sync.WaitGroup
   3154 	for _, p := range prog.packages {
   3155 		if prog.mode&BuildSerially != 0 {
   3156 			p.Build()
   3157 		} else {
   3158 			wg.Add(1)
   3159 			cpuLimit <- unit{} // acquire a token
   3160 			go func(p *Package) {
   3161 				p.Build()
   3162 				wg.Done()
   3163 				<-cpuLimit // release a token
   3164 			}(p)
   3165 		}
   3166 	}
   3167 	wg.Wait()
   3168 }
   3169 
   3170 // cpuLimit is a counting semaphore to limit CPU parallelism.
   3171 var cpuLimit = make(chan unit, runtime.GOMAXPROCS(0))
   3172 
   3173 // Build builds SSA code for all functions and vars in package p.
   3174 //
   3175 // CreatePackage must have been called for all of p's direct imports
   3176 // (and hence its direct imports must have been error-free). It is not
   3177 // necessary to call CreatePackage for indirect dependencies.
   3178 // Functions will be created for all necessary methods in those
   3179 // packages on demand.
   3180 //
   3181 // Build is idempotent and thread-safe.
   3182 func (p *Package) Build() { p.buildOnce.Do(p.build) }
   3183 
   3184 func (p *Package) build() {
   3185 	if p.info == nil {
   3186 		return // synthetic package, e.g. "testmain"
   3187 	}
   3188 	if p.Prog.mode&LogSource != 0 {
   3189 		defer logStack("build %s", p)()
   3190 	}
   3191 
   3192 	b := builder{fns: p.created}
   3193 	b.iterate()
   3194 
   3195 	// We no longer need transient information: ASTs or go/types deductions.
   3196 	p.info = nil
   3197 	p.created = nil
   3198 	p.files = nil
   3199 	p.initVersion = nil
   3200 
   3201 	if p.Prog.mode&SanityCheckFunctions != 0 {
   3202 		sanityCheckPackage(p)
   3203 	}
   3204 }
   3205 
   3206 // buildPackageInit builds fn.Body for the synthetic package initializer.
   3207 func (b *builder) buildPackageInit(fn *Function) {
   3208 	p := fn.Pkg
   3209 	fn.startBody()
   3210 
   3211 	var done *BasicBlock
   3212 
   3213 	if p.Prog.mode&BareInits == 0 {
   3214 		// Make init() skip if package is already initialized.
   3215 		initguard := p.Var("init$guard")
   3216 		doinit := fn.newBasicBlock("init.start")
   3217 		done = fn.newBasicBlock("init.done")
   3218 		emitIf(fn, emitLoad(fn, initguard), done, doinit)
   3219 		fn.currentBlock = doinit
   3220 		emitStore(fn, initguard, vTrue, token.NoPos)
   3221 
   3222 		// Call the init() function of each package we import.
   3223 		for _, pkg := range p.Pkg.Imports() {
   3224 			prereq := p.Prog.packages[pkg]
   3225 			if prereq == nil {
   3226 				panic(fmt.Sprintf("Package(%q).Build(): unsatisfied import: Program.CreatePackage(%q) was not called", p.Pkg.Path(), pkg.Path()))
   3227 			}
   3228 			var v Call
   3229 			v.Call.Value = prereq.init
   3230 			v.Call.pos = fn.pos
   3231 			v.setType(types.NewTuple())
   3232 			fn.emit(&v)
   3233 		}
   3234 	}
   3235 
   3236 	// Initialize package-level vars in correct order.
   3237 	if len(p.info.InitOrder) > 0 && len(p.files) == 0 {
   3238 		panic("no source files provided for package. cannot initialize globals")
   3239 	}
   3240 
   3241 	for _, varinit := range p.info.InitOrder {
   3242 		if fn.Prog.mode&LogSource != 0 {
   3243 			fmt.Fprintf(os.Stderr, "build global initializer %v @ %s\n",
   3244 				varinit.Lhs, p.Prog.Fset.Position(varinit.Rhs.Pos()))
   3245 		}
   3246 		// Initializers for global vars are evaluated in dependency
   3247 		// order, but may come from arbitrary files of the package
   3248 		// with different versions, so we transiently update
   3249 		// fn.goversion for each one. (Since init is a synthetic
   3250 		// function it has no syntax of its own that needs a version.)
   3251 		fn.goversion = p.initVersion[varinit.Rhs]
   3252 		if len(varinit.Lhs) == 1 {
   3253 			// 1:1 initialization: var x, y = a(), b()
   3254 			var lval lvalue
   3255 			if v := varinit.Lhs[0]; v.Name() != "_" {
   3256 				lval = &address{addr: p.objects[v].(*Global), pos: v.Pos()}
   3257 			} else {
   3258 				lval = blank{}
   3259 			}
   3260 			b.assign(fn, lval, varinit.Rhs, true, nil)
   3261 		} else {
   3262 			// n:1 initialization: var x, y :=  f()
   3263 			tuple := b.exprN(fn, varinit.Rhs)
   3264 			for i, v := range varinit.Lhs {
   3265 				if v.Name() == "_" {
   3266 					continue
   3267 				}
   3268 				emitStore(fn, p.objects[v].(*Global), emitExtract(fn, tuple, i), v.Pos())
   3269 			}
   3270 		}
   3271 	}
   3272 
   3273 	// The rest of the init function is synthetic:
   3274 	// no syntax, info, goversion.
   3275 	fn.info = nil
   3276 	fn.goversion = ""
   3277 
   3278 	// Call all of the declared init() functions in source order.
   3279 	for _, file := range p.files {
   3280 		for _, decl := range file.Decls {
   3281 			if decl, ok := decl.(*ast.FuncDecl); ok {
   3282 				id := decl.Name
   3283 				if !isBlankIdent(id) && id.Name == "init" && decl.Recv == nil {
   3284 					declaredInit := p.objects[p.info.Defs[id]].(*Function)
   3285 					var v Call
   3286 					v.Call.Value = declaredInit
   3287 					v.setType(types.NewTuple())
   3288 					p.init.emit(&v)
   3289 				}
   3290 			}
   3291 		}
   3292 	}
   3293 
   3294 	// Finish up init().
   3295 	if p.Prog.mode&BareInits == 0 {
   3296 		emitJump(fn, done)
   3297 		fn.currentBlock = done
   3298 	}
   3299 	fn.emit(new(Return))
   3300 	fn.finishBody()
   3301 }