Home | History | Annotate | Download | only in gc
      1 // Copyright 2009 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 gc
      6 
      7 import (
      8 	"cmd/compile/internal/types"
      9 	"cmd/internal/objabi"
     10 	"cmd/internal/src"
     11 	"crypto/md5"
     12 	"encoding/binary"
     13 	"fmt"
     14 	"os"
     15 	"runtime/debug"
     16 	"sort"
     17 	"strconv"
     18 	"strings"
     19 	"sync"
     20 	"unicode"
     21 	"unicode/utf8"
     22 )
     23 
     24 type Error struct {
     25 	pos src.XPos
     26 	msg string
     27 }
     28 
     29 var errors []Error
     30 
     31 var (
     32 	largeStackFramesMu sync.Mutex // protects largeStackFrames
     33 	largeStackFrames   []src.XPos // positions of functions whose stack frames are too large (rare)
     34 )
     35 
     36 func errorexit() {
     37 	flusherrors()
     38 	if outfile != "" {
     39 		os.Remove(outfile)
     40 	}
     41 	os.Exit(2)
     42 }
     43 
     44 func adderrorname(n *Node) {
     45 	if n.Op != ODOT {
     46 		return
     47 	}
     48 	old := fmt.Sprintf("%v: undefined: %v\n", n.Line(), n.Left)
     49 	if len(errors) > 0 && errors[len(errors)-1].pos.Line() == n.Pos.Line() && errors[len(errors)-1].msg == old {
     50 		errors[len(errors)-1].msg = fmt.Sprintf("%v: undefined: %v in %v\n", n.Line(), n.Left, n)
     51 	}
     52 }
     53 
     54 func adderr(pos src.XPos, format string, args ...interface{}) {
     55 	errors = append(errors, Error{
     56 		pos: pos,
     57 		msg: fmt.Sprintf("%v: %s\n", linestr(pos), fmt.Sprintf(format, args...)),
     58 	})
     59 }
     60 
     61 // byPos sorts errors by source position.
     62 type byPos []Error
     63 
     64 func (x byPos) Len() int           { return len(x) }
     65 func (x byPos) Less(i, j int) bool { return x[i].pos.Before(x[j].pos) }
     66 func (x byPos) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
     67 
     68 // flusherrors sorts errors seen so far by line number, prints them to stdout,
     69 // and empties the errors array.
     70 func flusherrors() {
     71 	Ctxt.Bso.Flush()
     72 	if len(errors) == 0 {
     73 		return
     74 	}
     75 	sort.Stable(byPos(errors))
     76 	for i := 0; i < len(errors); i++ {
     77 		if i == 0 || errors[i].msg != errors[i-1].msg {
     78 			fmt.Printf("%s", errors[i].msg)
     79 		}
     80 	}
     81 	errors = errors[:0]
     82 }
     83 
     84 func hcrash() {
     85 	if Debug['h'] != 0 {
     86 		flusherrors()
     87 		if outfile != "" {
     88 			os.Remove(outfile)
     89 		}
     90 		var x *int
     91 		*x = 0
     92 	}
     93 }
     94 
     95 func linestr(pos src.XPos) string {
     96 	return Ctxt.OutermostPos(pos).Format(Debug['C'] == 0, Debug['L'] == 1)
     97 }
     98 
     99 // lasterror keeps track of the most recently issued error.
    100 // It is used to avoid multiple error messages on the same
    101 // line.
    102 var lasterror struct {
    103 	syntax src.XPos // source position of last syntax error
    104 	other  src.XPos // source position of last non-syntax error
    105 	msg    string   // error message of last non-syntax error
    106 }
    107 
    108 // sameline reports whether two positions a, b are on the same line.
    109 func sameline(a, b src.XPos) bool {
    110 	p := Ctxt.PosTable.Pos(a)
    111 	q := Ctxt.PosTable.Pos(b)
    112 	return p.Base() == q.Base() && p.Line() == q.Line()
    113 }
    114 
    115 func yyerrorl(pos src.XPos, format string, args ...interface{}) {
    116 	msg := fmt.Sprintf(format, args...)
    117 
    118 	if strings.HasPrefix(msg, "syntax error") {
    119 		nsyntaxerrors++
    120 		// only one syntax error per line, no matter what error
    121 		if sameline(lasterror.syntax, pos) {
    122 			return
    123 		}
    124 		lasterror.syntax = pos
    125 	} else {
    126 		// only one of multiple equal non-syntax errors per line
    127 		// (flusherrors shows only one of them, so we filter them
    128 		// here as best as we can (they may not appear in order)
    129 		// so that we don't count them here and exit early, and
    130 		// then have nothing to show for.)
    131 		if sameline(lasterror.other, pos) && lasterror.msg == msg {
    132 			return
    133 		}
    134 		lasterror.other = pos
    135 		lasterror.msg = msg
    136 	}
    137 
    138 	adderr(pos, "%s", msg)
    139 
    140 	hcrash()
    141 	nerrors++
    142 	if nsavederrors+nerrors >= 10 && Debug['e'] == 0 {
    143 		flusherrors()
    144 		fmt.Printf("%v: too many errors\n", linestr(pos))
    145 		errorexit()
    146 	}
    147 }
    148 
    149 func yyerror(format string, args ...interface{}) {
    150 	yyerrorl(lineno, format, args...)
    151 }
    152 
    153 func Warn(fmt_ string, args ...interface{}) {
    154 	adderr(lineno, fmt_, args...)
    155 
    156 	hcrash()
    157 }
    158 
    159 func Warnl(line src.XPos, fmt_ string, args ...interface{}) {
    160 	adderr(line, fmt_, args...)
    161 	if Debug['m'] != 0 {
    162 		flusherrors()
    163 	}
    164 }
    165 
    166 func Fatalf(fmt_ string, args ...interface{}) {
    167 	flusherrors()
    168 
    169 	if Debug_panic != 0 || nsavederrors+nerrors == 0 {
    170 		fmt.Printf("%v: internal compiler error: ", linestr(lineno))
    171 		fmt.Printf(fmt_, args...)
    172 		fmt.Printf("\n")
    173 
    174 		// If this is a released compiler version, ask for a bug report.
    175 		if strings.HasPrefix(objabi.Version, "go") {
    176 			fmt.Printf("\n")
    177 			fmt.Printf("Please file a bug report including a short program that triggers the error.\n")
    178 			fmt.Printf("https://golang.org/issue/new\n")
    179 		} else {
    180 			// Not a release; dump a stack trace, too.
    181 			fmt.Println()
    182 			os.Stdout.Write(debug.Stack())
    183 			fmt.Println()
    184 		}
    185 	}
    186 
    187 	hcrash()
    188 	errorexit()
    189 }
    190 
    191 func setlineno(n *Node) src.XPos {
    192 	lno := lineno
    193 	if n != nil {
    194 		switch n.Op {
    195 		case ONAME, OPACK:
    196 			break
    197 
    198 		case OLITERAL, OTYPE:
    199 			if n.Sym != nil {
    200 				break
    201 			}
    202 			fallthrough
    203 
    204 		default:
    205 			lineno = n.Pos
    206 			if !lineno.IsKnown() {
    207 				if Debug['K'] != 0 {
    208 					Warn("setlineno: unknown position (line 0)")
    209 				}
    210 				lineno = lno
    211 			}
    212 		}
    213 	}
    214 
    215 	return lno
    216 }
    217 
    218 func lookup(name string) *types.Sym {
    219 	return localpkg.Lookup(name)
    220 }
    221 
    222 // lookupN looks up the symbol starting with prefix and ending with
    223 // the decimal n. If prefix is too long, lookupN panics.
    224 func lookupN(prefix string, n int) *types.Sym {
    225 	var buf [20]byte // plenty long enough for all current users
    226 	copy(buf[:], prefix)
    227 	b := strconv.AppendInt(buf[:len(prefix)], int64(n), 10)
    228 	return localpkg.LookupBytes(b)
    229 }
    230 
    231 // autolabel generates a new Name node for use with
    232 // an automatically generated label.
    233 // prefix is a short mnemonic (e.g. ".s" for switch)
    234 // to help with debugging.
    235 // It should begin with "." to avoid conflicts with
    236 // user labels.
    237 func autolabel(prefix string) *Node {
    238 	if prefix[0] != '.' {
    239 		Fatalf("autolabel prefix must start with '.', have %q", prefix)
    240 	}
    241 	fn := Curfn
    242 	if Curfn == nil {
    243 		Fatalf("autolabel outside function")
    244 	}
    245 	n := fn.Func.Label
    246 	fn.Func.Label++
    247 	return newname(lookupN(prefix, int(n)))
    248 }
    249 
    250 func restrictlookup(name string, pkg *types.Pkg) *types.Sym {
    251 	if !exportname(name) && pkg != localpkg {
    252 		yyerror("cannot refer to unexported name %s.%s", pkg.Name, name)
    253 	}
    254 	return pkg.Lookup(name)
    255 }
    256 
    257 // find all the exported symbols in package opkg
    258 // and make them available in the current package
    259 func importdot(opkg *types.Pkg, pack *Node) {
    260 	n := 0
    261 	for _, s := range opkg.Syms {
    262 		if s.Def == nil {
    263 			continue
    264 		}
    265 		if !exportname(s.Name) || strings.ContainsRune(s.Name, 0xb7) { // 0xb7 = center dot
    266 			continue
    267 		}
    268 		s1 := lookup(s.Name)
    269 		if s1.Def != nil {
    270 			pkgerror := fmt.Sprintf("during import %q", opkg.Path)
    271 			redeclare(s1, pkgerror)
    272 			continue
    273 		}
    274 
    275 		s1.Def = s.Def
    276 		s1.Block = s.Block
    277 		if asNode(s1.Def).Name == nil {
    278 			Dump("s1def", asNode(s1.Def))
    279 			Fatalf("missing Name")
    280 		}
    281 		asNode(s1.Def).Name.Pack = pack
    282 		s1.Origpkg = opkg
    283 		n++
    284 	}
    285 
    286 	if n == 0 {
    287 		// can't possibly be used - there were no symbols
    288 		yyerrorl(pack.Pos, "imported and not used: %q", opkg.Path)
    289 	}
    290 }
    291 
    292 func nod(op Op, nleft, nright *Node) *Node {
    293 	return nodl(lineno, op, nleft, nright)
    294 }
    295 
    296 func nodl(pos src.XPos, op Op, nleft, nright *Node) *Node {
    297 	var n *Node
    298 	switch op {
    299 	case OCLOSURE, ODCLFUNC:
    300 		var x struct {
    301 			Node
    302 			Func
    303 		}
    304 		n = &x.Node
    305 		n.Func = &x.Func
    306 	case ONAME:
    307 		Fatalf("use newname instead")
    308 	case OLABEL, OPACK:
    309 		var x struct {
    310 			Node
    311 			Name
    312 		}
    313 		n = &x.Node
    314 		n.Name = &x.Name
    315 	default:
    316 		n = new(Node)
    317 	}
    318 	n.Op = op
    319 	n.Left = nleft
    320 	n.Right = nright
    321 	n.Pos = pos
    322 	n.Xoffset = BADWIDTH
    323 	n.Orig = n
    324 	return n
    325 }
    326 
    327 // newname returns a new ONAME Node associated with symbol s.
    328 func newname(s *types.Sym) *Node {
    329 	n := newnamel(lineno, s)
    330 	n.Name.Curfn = Curfn
    331 	return n
    332 }
    333 
    334 // newname returns a new ONAME Node associated with symbol s at position pos.
    335 // The caller is responsible for setting n.Name.Curfn.
    336 func newnamel(pos src.XPos, s *types.Sym) *Node {
    337 	if s == nil {
    338 		Fatalf("newnamel nil")
    339 	}
    340 
    341 	var x struct {
    342 		Node
    343 		Name
    344 		Param
    345 	}
    346 	n := &x.Node
    347 	n.Name = &x.Name
    348 	n.Name.Param = &x.Param
    349 
    350 	n.Op = ONAME
    351 	n.Pos = pos
    352 	n.Orig = n
    353 
    354 	n.Sym = s
    355 	n.SetAddable(true)
    356 	return n
    357 }
    358 
    359 // nodSym makes a Node with Op op and with the Left field set to left
    360 // and the Sym field set to sym. This is for ODOT and friends.
    361 func nodSym(op Op, left *Node, sym *types.Sym) *Node {
    362 	n := nod(op, left, nil)
    363 	n.Sym = sym
    364 	return n
    365 }
    366 
    367 func saveorignode(n *Node) {
    368 	if n.Orig != nil {
    369 		return
    370 	}
    371 	norig := nod(n.Op, nil, nil)
    372 	*norig = *n
    373 	n.Orig = norig
    374 }
    375 
    376 // methcmp sorts by symbol, then by package path for unexported symbols.
    377 type methcmp []*types.Field
    378 
    379 func (x methcmp) Len() int      { return len(x) }
    380 func (x methcmp) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
    381 func (x methcmp) Less(i, j int) bool {
    382 	a := x[i]
    383 	b := x[j]
    384 	if a.Sym == nil && b.Sym == nil {
    385 		return false
    386 	}
    387 	if a.Sym == nil {
    388 		return true
    389 	}
    390 	if b.Sym == nil {
    391 		return false
    392 	}
    393 	if a.Sym.Name != b.Sym.Name {
    394 		return a.Sym.Name < b.Sym.Name
    395 	}
    396 	if !exportname(a.Sym.Name) {
    397 		if a.Sym.Pkg.Path != b.Sym.Pkg.Path {
    398 			return a.Sym.Pkg.Path < b.Sym.Pkg.Path
    399 		}
    400 	}
    401 
    402 	return false
    403 }
    404 
    405 func nodintconst(v int64) *Node {
    406 	c := nod(OLITERAL, nil, nil)
    407 	c.SetAddable(true)
    408 	c.SetVal(Val{new(Mpint)})
    409 	c.Val().U.(*Mpint).SetInt64(v)
    410 	c.Type = types.Types[TIDEAL]
    411 	return c
    412 }
    413 
    414 func nodfltconst(v *Mpflt) *Node {
    415 	c := nod(OLITERAL, nil, nil)
    416 	c.SetAddable(true)
    417 	c.SetVal(Val{newMpflt()})
    418 	c.Val().U.(*Mpflt).Set(v)
    419 	c.Type = types.Types[TIDEAL]
    420 	return c
    421 }
    422 
    423 func nodconst(n *Node, t *types.Type, v int64) {
    424 	*n = Node{}
    425 	n.Op = OLITERAL
    426 	n.SetAddable(true)
    427 	n.SetVal(Val{new(Mpint)})
    428 	n.Val().U.(*Mpint).SetInt64(v)
    429 	n.Type = t
    430 
    431 	if t.IsFloat() {
    432 		Fatalf("nodconst: bad type %v", t)
    433 	}
    434 }
    435 
    436 func nodnil() *Node {
    437 	c := nodintconst(0)
    438 	c.SetVal(Val{new(NilVal)})
    439 	c.Type = types.Types[TNIL]
    440 	return c
    441 }
    442 
    443 func nodbool(b bool) *Node {
    444 	c := nodintconst(0)
    445 	c.SetVal(Val{b})
    446 	c.Type = types.Idealbool
    447 	return c
    448 }
    449 
    450 func nodstr(s string) *Node {
    451 	return nodlit(Val{s})
    452 }
    453 
    454 // treecopy recursively copies n, with the exception of
    455 // ONAME, OLITERAL, OTYPE, and non-iota ONONAME leaves.
    456 // Copies of iota ONONAME nodes are assigned the current
    457 // value of iota_. If pos.IsKnown(), it sets the source
    458 // position of newly allocated nodes to pos.
    459 func treecopy(n *Node, pos src.XPos) *Node {
    460 	if n == nil {
    461 		return nil
    462 	}
    463 
    464 	switch n.Op {
    465 	default:
    466 		m := *n
    467 		m.Orig = &m
    468 		m.Left = treecopy(n.Left, pos)
    469 		m.Right = treecopy(n.Right, pos)
    470 		m.List.Set(listtreecopy(n.List.Slice(), pos))
    471 		if pos.IsKnown() {
    472 			m.Pos = pos
    473 		}
    474 		if m.Name != nil && n.Op != ODCLFIELD {
    475 			Dump("treecopy", n)
    476 			Fatalf("treecopy Name")
    477 		}
    478 		return &m
    479 
    480 	case OPACK:
    481 		// OPACK nodes are never valid in const value declarations,
    482 		// but allow them like any other declared symbol to avoid
    483 		// crashing (golang.org/issue/11361).
    484 		fallthrough
    485 
    486 	case ONAME, ONONAME, OLITERAL, OTYPE:
    487 		return n
    488 
    489 	}
    490 }
    491 
    492 // isnil reports whether n represents the universal untyped zero value "nil".
    493 func isnil(n *Node) bool {
    494 	// Check n.Orig because constant propagation may produce typed nil constants,
    495 	// which don't exist in the Go spec.
    496 	return Isconst(n.Orig, CTNIL)
    497 }
    498 
    499 func isptrto(t *types.Type, et types.EType) bool {
    500 	if t == nil {
    501 		return false
    502 	}
    503 	if !t.IsPtr() {
    504 		return false
    505 	}
    506 	t = t.Elem()
    507 	if t == nil {
    508 		return false
    509 	}
    510 	if t.Etype != et {
    511 		return false
    512 	}
    513 	return true
    514 }
    515 
    516 func isblank(n *Node) bool {
    517 	if n == nil {
    518 		return false
    519 	}
    520 	return n.Sym.IsBlank()
    521 }
    522 
    523 // methtype returns the underlying type, if any,
    524 // that owns methods with receiver parameter t.
    525 // The result is either a named type or an anonymous struct.
    526 func methtype(t *types.Type) *types.Type {
    527 	if t == nil {
    528 		return nil
    529 	}
    530 
    531 	// Strip away pointer if it's there.
    532 	if t.IsPtr() {
    533 		if t.Sym != nil {
    534 			return nil
    535 		}
    536 		t = t.Elem()
    537 		if t == nil {
    538 			return nil
    539 		}
    540 	}
    541 
    542 	// Must be a named type or anonymous struct.
    543 	if t.Sym == nil && !t.IsStruct() {
    544 		return nil
    545 	}
    546 
    547 	// Check types.
    548 	if issimple[t.Etype] {
    549 		return t
    550 	}
    551 	switch t.Etype {
    552 	case TARRAY, TCHAN, TFUNC, TMAP, TSLICE, TSTRING, TSTRUCT:
    553 		return t
    554 	}
    555 	return nil
    556 }
    557 
    558 // eqtype reports whether t1 and t2 are identical, following the spec rules.
    559 //
    560 // Any cyclic type must go through a named type, and if one is
    561 // named, it is only identical to the other if they are the same
    562 // pointer (t1 == t2), so there's no chance of chasing cycles
    563 // ad infinitum, so no need for a depth counter.
    564 func eqtype(t1, t2 *types.Type) bool {
    565 	return eqtype1(t1, t2, true, nil)
    566 }
    567 
    568 // eqtypeIgnoreTags is like eqtype but it ignores struct tags for struct identity.
    569 func eqtypeIgnoreTags(t1, t2 *types.Type) bool {
    570 	return eqtype1(t1, t2, false, nil)
    571 }
    572 
    573 type typePair struct {
    574 	t1 *types.Type
    575 	t2 *types.Type
    576 }
    577 
    578 func eqtype1(t1, t2 *types.Type, cmpTags bool, assumedEqual map[typePair]struct{}) bool {
    579 	if t1 == t2 {
    580 		return true
    581 	}
    582 	if t1 == nil || t2 == nil || t1.Etype != t2.Etype || t1.Broke() || t2.Broke() {
    583 		return false
    584 	}
    585 	if t1.Sym != nil || t2.Sym != nil {
    586 		// Special case: we keep byte/uint8 and rune/int32
    587 		// separate for error messages. Treat them as equal.
    588 		switch t1.Etype {
    589 		case TUINT8:
    590 			return (t1 == types.Types[TUINT8] || t1 == types.Bytetype) && (t2 == types.Types[TUINT8] || t2 == types.Bytetype)
    591 		case TINT32:
    592 			return (t1 == types.Types[TINT32] || t1 == types.Runetype) && (t2 == types.Types[TINT32] || t2 == types.Runetype)
    593 		default:
    594 			return false
    595 		}
    596 	}
    597 
    598 	if assumedEqual == nil {
    599 		assumedEqual = make(map[typePair]struct{})
    600 	} else if _, ok := assumedEqual[typePair{t1, t2}]; ok {
    601 		return true
    602 	}
    603 	assumedEqual[typePair{t1, t2}] = struct{}{}
    604 
    605 	switch t1.Etype {
    606 	case TINTER:
    607 		if t1.NumFields() != t2.NumFields() {
    608 			return false
    609 		}
    610 		for i, f1 := range t1.FieldSlice() {
    611 			f2 := t2.Field(i)
    612 			if f1.Sym != f2.Sym || !eqtype1(f1.Type, f2.Type, cmpTags, assumedEqual) {
    613 				return false
    614 			}
    615 		}
    616 		return true
    617 
    618 	case TSTRUCT:
    619 		if t1.NumFields() != t2.NumFields() {
    620 			return false
    621 		}
    622 		for i, f1 := range t1.FieldSlice() {
    623 			f2 := t2.Field(i)
    624 			if f1.Sym != f2.Sym || f1.Embedded != f2.Embedded || !eqtype1(f1.Type, f2.Type, cmpTags, assumedEqual) {
    625 				return false
    626 			}
    627 			if cmpTags && f1.Note != f2.Note {
    628 				return false
    629 			}
    630 		}
    631 		return true
    632 
    633 	case TFUNC:
    634 		// Check parameters and result parameters for type equality.
    635 		// We intentionally ignore receiver parameters for type
    636 		// equality, because they're never relevant.
    637 		for _, f := range types.ParamsResults {
    638 			// Loop over fields in structs, ignoring argument names.
    639 			fs1, fs2 := f(t1).FieldSlice(), f(t2).FieldSlice()
    640 			if len(fs1) != len(fs2) {
    641 				return false
    642 			}
    643 			for i, f1 := range fs1 {
    644 				f2 := fs2[i]
    645 				if f1.Isddd() != f2.Isddd() || !eqtype1(f1.Type, f2.Type, cmpTags, assumedEqual) {
    646 					return false
    647 				}
    648 			}
    649 		}
    650 		return true
    651 
    652 	case TARRAY:
    653 		if t1.NumElem() != t2.NumElem() {
    654 			return false
    655 		}
    656 
    657 	case TCHAN:
    658 		if t1.ChanDir() != t2.ChanDir() {
    659 			return false
    660 		}
    661 
    662 	case TMAP:
    663 		if !eqtype1(t1.Key(), t2.Key(), cmpTags, assumedEqual) {
    664 			return false
    665 		}
    666 		return eqtype1(t1.Val(), t2.Val(), cmpTags, assumedEqual)
    667 	}
    668 
    669 	return eqtype1(t1.Elem(), t2.Elem(), cmpTags, assumedEqual)
    670 }
    671 
    672 // Are t1 and t2 equal struct types when field names are ignored?
    673 // For deciding whether the result struct from g can be copied
    674 // directly when compiling f(g()).
    675 func eqtypenoname(t1 *types.Type, t2 *types.Type) bool {
    676 	if t1 == nil || t2 == nil || !t1.IsStruct() || !t2.IsStruct() {
    677 		return false
    678 	}
    679 
    680 	if t1.NumFields() != t2.NumFields() {
    681 		return false
    682 	}
    683 	for i, f1 := range t1.FieldSlice() {
    684 		f2 := t2.Field(i)
    685 		if !eqtype(f1.Type, f2.Type) {
    686 			return false
    687 		}
    688 	}
    689 	return true
    690 }
    691 
    692 // Is type src assignment compatible to type dst?
    693 // If so, return op code to use in conversion.
    694 // If not, return 0.
    695 func assignop(src *types.Type, dst *types.Type, why *string) Op {
    696 	if why != nil {
    697 		*why = ""
    698 	}
    699 
    700 	// TODO(rsc,lvd): This behaves poorly in the presence of inlining.
    701 	// https://golang.org/issue/2795
    702 	if safemode && !inimport && src != nil && src.Etype == TUNSAFEPTR {
    703 		yyerror("cannot use unsafe.Pointer")
    704 		errorexit()
    705 	}
    706 
    707 	if src == dst {
    708 		return OCONVNOP
    709 	}
    710 	if src == nil || dst == nil || src.Etype == TFORW || dst.Etype == TFORW || src.Orig == nil || dst.Orig == nil {
    711 		return 0
    712 	}
    713 
    714 	// 1. src type is identical to dst.
    715 	if eqtype(src, dst) {
    716 		return OCONVNOP
    717 	}
    718 
    719 	// 2. src and dst have identical underlying types
    720 	// and either src or dst is not a named type or
    721 	// both are empty interface types.
    722 	// For assignable but different non-empty interface types,
    723 	// we want to recompute the itab. Recomputing the itab ensures
    724 	// that itabs are unique (thus an interface with a compile-time
    725 	// type I has an itab with interface type I).
    726 	if eqtype(src.Orig, dst.Orig) {
    727 		if src.IsEmptyInterface() {
    728 			// Conversion between two empty interfaces
    729 			// requires no code.
    730 			return OCONVNOP
    731 		}
    732 		if (src.Sym == nil || dst.Sym == nil) && !src.IsInterface() {
    733 			// Conversion between two types, at least one unnamed,
    734 			// needs no conversion. The exception is nonempty interfaces
    735 			// which need to have their itab updated.
    736 			return OCONVNOP
    737 		}
    738 	}
    739 
    740 	// 3. dst is an interface type and src implements dst.
    741 	if dst.IsInterface() && src.Etype != TNIL {
    742 		var missing, have *types.Field
    743 		var ptr int
    744 		if implements(src, dst, &missing, &have, &ptr) {
    745 			return OCONVIFACE
    746 		}
    747 
    748 		// we'll have complained about this method anyway, suppress spurious messages.
    749 		if have != nil && have.Sym == missing.Sym && (have.Type.Broke() || missing.Type.Broke()) {
    750 			return OCONVIFACE
    751 		}
    752 
    753 		if why != nil {
    754 			if isptrto(src, TINTER) {
    755 				*why = fmt.Sprintf(":\n\t%v is pointer to interface, not interface", src)
    756 			} else if have != nil && have.Sym == missing.Sym && have.Nointerface() {
    757 				*why = fmt.Sprintf(":\n\t%v does not implement %v (%v method is marked 'nointerface')", src, dst, missing.Sym)
    758 			} else if have != nil && have.Sym == missing.Sym {
    759 				*why = fmt.Sprintf(":\n\t%v does not implement %v (wrong type for %v method)\n"+
    760 					"\t\thave %v%0S\n\t\twant %v%0S", src, dst, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
    761 			} else if ptr != 0 {
    762 				*why = fmt.Sprintf(":\n\t%v does not implement %v (%v method has pointer receiver)", src, dst, missing.Sym)
    763 			} else if have != nil {
    764 				*why = fmt.Sprintf(":\n\t%v does not implement %v (missing %v method)\n"+
    765 					"\t\thave %v%0S\n\t\twant %v%0S", src, dst, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
    766 			} else {
    767 				*why = fmt.Sprintf(":\n\t%v does not implement %v (missing %v method)", src, dst, missing.Sym)
    768 			}
    769 		}
    770 
    771 		return 0
    772 	}
    773 
    774 	if isptrto(dst, TINTER) {
    775 		if why != nil {
    776 			*why = fmt.Sprintf(":\n\t%v is pointer to interface, not interface", dst)
    777 		}
    778 		return 0
    779 	}
    780 
    781 	if src.IsInterface() && dst.Etype != TBLANK {
    782 		var missing, have *types.Field
    783 		var ptr int
    784 		if why != nil && implements(dst, src, &missing, &have, &ptr) {
    785 			*why = ": need type assertion"
    786 		}
    787 		return 0
    788 	}
    789 
    790 	// 4. src is a bidirectional channel value, dst is a channel type,
    791 	// src and dst have identical element types, and
    792 	// either src or dst is not a named type.
    793 	if src.IsChan() && src.ChanDir() == types.Cboth && dst.IsChan() {
    794 		if eqtype(src.Elem(), dst.Elem()) && (src.Sym == nil || dst.Sym == nil) {
    795 			return OCONVNOP
    796 		}
    797 	}
    798 
    799 	// 5. src is the predeclared identifier nil and dst is a nillable type.
    800 	if src.Etype == TNIL {
    801 		switch dst.Etype {
    802 		case TPTR32,
    803 			TPTR64,
    804 			TFUNC,
    805 			TMAP,
    806 			TCHAN,
    807 			TINTER,
    808 			TSLICE:
    809 			return OCONVNOP
    810 		}
    811 	}
    812 
    813 	// 6. rule about untyped constants - already converted by defaultlit.
    814 
    815 	// 7. Any typed value can be assigned to the blank identifier.
    816 	if dst.Etype == TBLANK {
    817 		return OCONVNOP
    818 	}
    819 
    820 	return 0
    821 }
    822 
    823 // Can we convert a value of type src to a value of type dst?
    824 // If so, return op code to use in conversion (maybe OCONVNOP).
    825 // If not, return 0.
    826 func convertop(src *types.Type, dst *types.Type, why *string) Op {
    827 	if why != nil {
    828 		*why = ""
    829 	}
    830 
    831 	if src == dst {
    832 		return OCONVNOP
    833 	}
    834 	if src == nil || dst == nil {
    835 		return 0
    836 	}
    837 
    838 	// Conversions from regular to go:notinheap are not allowed
    839 	// (unless it's unsafe.Pointer). This is a runtime-specific
    840 	// rule.
    841 	if src.IsPtr() && dst.IsPtr() && dst.Elem().NotInHeap() && !src.Elem().NotInHeap() {
    842 		if why != nil {
    843 			*why = fmt.Sprintf(":\n\t%v is go:notinheap, but %v is not", dst.Elem(), src.Elem())
    844 		}
    845 		return 0
    846 	}
    847 
    848 	// 1. src can be assigned to dst.
    849 	op := assignop(src, dst, why)
    850 	if op != 0 {
    851 		return op
    852 	}
    853 
    854 	// The rules for interfaces are no different in conversions
    855 	// than assignments. If interfaces are involved, stop now
    856 	// with the good message from assignop.
    857 	// Otherwise clear the error.
    858 	if src.IsInterface() || dst.IsInterface() {
    859 		return 0
    860 	}
    861 	if why != nil {
    862 		*why = ""
    863 	}
    864 
    865 	// 2. Ignoring struct tags, src and dst have identical underlying types.
    866 	if eqtypeIgnoreTags(src.Orig, dst.Orig) {
    867 		return OCONVNOP
    868 	}
    869 
    870 	// 3. src and dst are unnamed pointer types and, ignoring struct tags,
    871 	// their base types have identical underlying types.
    872 	if src.IsPtr() && dst.IsPtr() && src.Sym == nil && dst.Sym == nil {
    873 		if eqtypeIgnoreTags(src.Elem().Orig, dst.Elem().Orig) {
    874 			return OCONVNOP
    875 		}
    876 	}
    877 
    878 	// 4. src and dst are both integer or floating point types.
    879 	if (src.IsInteger() || src.IsFloat()) && (dst.IsInteger() || dst.IsFloat()) {
    880 		if simtype[src.Etype] == simtype[dst.Etype] {
    881 			return OCONVNOP
    882 		}
    883 		return OCONV
    884 	}
    885 
    886 	// 5. src and dst are both complex types.
    887 	if src.IsComplex() && dst.IsComplex() {
    888 		if simtype[src.Etype] == simtype[dst.Etype] {
    889 			return OCONVNOP
    890 		}
    891 		return OCONV
    892 	}
    893 
    894 	// 6. src is an integer or has type []byte or []rune
    895 	// and dst is a string type.
    896 	if src.IsInteger() && dst.IsString() {
    897 		return ORUNESTR
    898 	}
    899 
    900 	if src.IsSlice() && dst.IsString() {
    901 		if src.Elem().Etype == types.Bytetype.Etype {
    902 			return OARRAYBYTESTR
    903 		}
    904 		if src.Elem().Etype == types.Runetype.Etype {
    905 			return OARRAYRUNESTR
    906 		}
    907 	}
    908 
    909 	// 7. src is a string and dst is []byte or []rune.
    910 	// String to slice.
    911 	if src.IsString() && dst.IsSlice() {
    912 		if dst.Elem().Etype == types.Bytetype.Etype {
    913 			return OSTRARRAYBYTE
    914 		}
    915 		if dst.Elem().Etype == types.Runetype.Etype {
    916 			return OSTRARRAYRUNE
    917 		}
    918 	}
    919 
    920 	// 8. src is a pointer or uintptr and dst is unsafe.Pointer.
    921 	if (src.IsPtr() || src.Etype == TUINTPTR) && dst.Etype == TUNSAFEPTR {
    922 		return OCONVNOP
    923 	}
    924 
    925 	// 9. src is unsafe.Pointer and dst is a pointer or uintptr.
    926 	if src.Etype == TUNSAFEPTR && (dst.IsPtr() || dst.Etype == TUINTPTR) {
    927 		return OCONVNOP
    928 	}
    929 
    930 	// src is map and dst is a pointer to corresponding hmap.
    931 	// This rule is needed for the implementation detail that
    932 	// go gc maps are implemented as a pointer to a hmap struct.
    933 	if src.Etype == TMAP && dst.IsPtr() &&
    934 		src.MapType().Hmap == dst.Elem() {
    935 		return OCONVNOP
    936 	}
    937 
    938 	return 0
    939 }
    940 
    941 func assignconv(n *Node, t *types.Type, context string) *Node {
    942 	return assignconvfn(n, t, func() string { return context })
    943 }
    944 
    945 // Convert node n for assignment to type t.
    946 func assignconvfn(n *Node, t *types.Type, context func() string) *Node {
    947 	if n == nil || n.Type == nil || n.Type.Broke() {
    948 		return n
    949 	}
    950 
    951 	if t.Etype == TBLANK && n.Type.Etype == TNIL {
    952 		yyerror("use of untyped nil")
    953 	}
    954 
    955 	old := n
    956 	od := old.Diag()
    957 	old.SetDiag(true) // silence errors about n; we'll issue one below
    958 	n = defaultlit(n, t)
    959 	old.SetDiag(od)
    960 	if t.Etype == TBLANK {
    961 		return n
    962 	}
    963 
    964 	// Convert ideal bool from comparison to plain bool
    965 	// if the next step is non-bool (like interface{}).
    966 	if n.Type == types.Idealbool && !t.IsBoolean() {
    967 		if n.Op == ONAME || n.Op == OLITERAL {
    968 			r := nod(OCONVNOP, n, nil)
    969 			r.Type = types.Types[TBOOL]
    970 			r.SetTypecheck(1)
    971 			r.SetImplicit(true)
    972 			n = r
    973 		}
    974 	}
    975 
    976 	if eqtype(n.Type, t) {
    977 		return n
    978 	}
    979 
    980 	var why string
    981 	op := assignop(n.Type, t, &why)
    982 	if op == 0 {
    983 		if !old.Diag() {
    984 			yyerror("cannot use %L as type %v in %s%s", n, t, context(), why)
    985 		}
    986 		op = OCONV
    987 	}
    988 
    989 	r := nod(op, n, nil)
    990 	r.Type = t
    991 	r.SetTypecheck(1)
    992 	r.SetImplicit(true)
    993 	r.Orig = n.Orig
    994 	return r
    995 }
    996 
    997 // IsMethod reports whether n is a method.
    998 // n must be a function or a method.
    999 func (n *Node) IsMethod() bool {
   1000 	return n.Type.Recv() != nil
   1001 }
   1002 
   1003 // SliceBounds returns n's slice bounds: low, high, and max in expr[low:high:max].
   1004 // n must be a slice expression. max is nil if n is a simple slice expression.
   1005 func (n *Node) SliceBounds() (low, high, max *Node) {
   1006 	if n.List.Len() == 0 {
   1007 		return nil, nil, nil
   1008 	}
   1009 
   1010 	switch n.Op {
   1011 	case OSLICE, OSLICEARR, OSLICESTR:
   1012 		s := n.List.Slice()
   1013 		return s[0], s[1], nil
   1014 	case OSLICE3, OSLICE3ARR:
   1015 		s := n.List.Slice()
   1016 		return s[0], s[1], s[2]
   1017 	}
   1018 	Fatalf("SliceBounds op %v: %v", n.Op, n)
   1019 	return nil, nil, nil
   1020 }
   1021 
   1022 // SetSliceBounds sets n's slice bounds, where n is a slice expression.
   1023 // n must be a slice expression. If max is non-nil, n must be a full slice expression.
   1024 func (n *Node) SetSliceBounds(low, high, max *Node) {
   1025 	switch n.Op {
   1026 	case OSLICE, OSLICEARR, OSLICESTR:
   1027 		if max != nil {
   1028 			Fatalf("SetSliceBounds %v given three bounds", n.Op)
   1029 		}
   1030 		s := n.List.Slice()
   1031 		if s == nil {
   1032 			if low == nil && high == nil {
   1033 				return
   1034 			}
   1035 			n.List.Set2(low, high)
   1036 			return
   1037 		}
   1038 		s[0] = low
   1039 		s[1] = high
   1040 		return
   1041 	case OSLICE3, OSLICE3ARR:
   1042 		s := n.List.Slice()
   1043 		if s == nil {
   1044 			if low == nil && high == nil && max == nil {
   1045 				return
   1046 			}
   1047 			n.List.Set3(low, high, max)
   1048 			return
   1049 		}
   1050 		s[0] = low
   1051 		s[1] = high
   1052 		s[2] = max
   1053 		return
   1054 	}
   1055 	Fatalf("SetSliceBounds op %v: %v", n.Op, n)
   1056 }
   1057 
   1058 // IsSlice3 reports whether o is a slice3 op (OSLICE3, OSLICE3ARR).
   1059 // o must be a slicing op.
   1060 func (o Op) IsSlice3() bool {
   1061 	switch o {
   1062 	case OSLICE, OSLICEARR, OSLICESTR:
   1063 		return false
   1064 	case OSLICE3, OSLICE3ARR:
   1065 		return true
   1066 	}
   1067 	Fatalf("IsSlice3 op %v", o)
   1068 	return false
   1069 }
   1070 
   1071 // labeledControl returns the control flow Node (for, switch, select)
   1072 // associated with the label n, if any.
   1073 func (n *Node) labeledControl() *Node {
   1074 	if n.Op != OLABEL {
   1075 		Fatalf("labeledControl %v", n.Op)
   1076 	}
   1077 	ctl := n.Name.Defn
   1078 	if ctl == nil {
   1079 		return nil
   1080 	}
   1081 	switch ctl.Op {
   1082 	case OFOR, OFORUNTIL, OSWITCH, OSELECT:
   1083 		return ctl
   1084 	}
   1085 	return nil
   1086 }
   1087 
   1088 func syslook(name string) *Node {
   1089 	s := Runtimepkg.Lookup(name)
   1090 	if s == nil || s.Def == nil {
   1091 		Fatalf("syslook: can't find runtime.%s", name)
   1092 	}
   1093 	return asNode(s.Def)
   1094 }
   1095 
   1096 // typehash computes a hash value for type t to use in type switch statements.
   1097 func typehash(t *types.Type) uint32 {
   1098 	p := t.LongString()
   1099 
   1100 	// Using MD5 is overkill, but reduces accidental collisions.
   1101 	h := md5.Sum([]byte(p))
   1102 	return binary.LittleEndian.Uint32(h[:4])
   1103 }
   1104 
   1105 func frame(context int) {
   1106 	if context != 0 {
   1107 		fmt.Printf("--- external frame ---\n")
   1108 		for _, n := range externdcl {
   1109 			printframenode(n)
   1110 		}
   1111 		return
   1112 	}
   1113 
   1114 	if Curfn != nil {
   1115 		fmt.Printf("--- %v frame ---\n", Curfn.Func.Nname.Sym)
   1116 		for _, ln := range Curfn.Func.Dcl {
   1117 			printframenode(ln)
   1118 		}
   1119 	}
   1120 }
   1121 
   1122 func printframenode(n *Node) {
   1123 	w := int64(-1)
   1124 	if n.Type != nil {
   1125 		w = n.Type.Width
   1126 	}
   1127 	switch n.Op {
   1128 	case ONAME:
   1129 		fmt.Printf("%v %v G%d %v width=%d\n", n.Op, n.Sym, n.Name.Vargen, n.Type, w)
   1130 	case OTYPE:
   1131 		fmt.Printf("%v %v width=%d\n", n.Op, n.Type, w)
   1132 	}
   1133 }
   1134 
   1135 // updateHasCall checks whether expression n contains any function
   1136 // calls and sets the n.HasCall flag if so.
   1137 func updateHasCall(n *Node) {
   1138 	if n == nil {
   1139 		return
   1140 	}
   1141 	n.SetHasCall(calcHasCall(n))
   1142 }
   1143 
   1144 func calcHasCall(n *Node) bool {
   1145 	if n.Ninit.Len() != 0 {
   1146 		// TODO(mdempsky): This seems overly conservative.
   1147 		return true
   1148 	}
   1149 
   1150 	switch n.Op {
   1151 	case OLITERAL, ONAME, OTYPE:
   1152 		if n.HasCall() {
   1153 			Fatalf("OLITERAL/ONAME/OTYPE should never have calls: %+v", n)
   1154 		}
   1155 		return false
   1156 	case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER:
   1157 		return true
   1158 	case OANDAND, OOROR:
   1159 		// hard with instrumented code
   1160 		if instrumenting {
   1161 			return true
   1162 		}
   1163 	case OINDEX, OSLICE, OSLICEARR, OSLICE3, OSLICE3ARR, OSLICESTR,
   1164 		OIND, ODOTPTR, ODOTTYPE, ODIV, OMOD:
   1165 		// These ops might panic, make sure they are done
   1166 		// before we start marshaling args for a call. See issue 16760.
   1167 		return true
   1168 
   1169 	// When using soft-float, these ops might be rewritten to function calls
   1170 	// so we ensure they are evaluated first.
   1171 	case OADD, OSUB, OMINUS:
   1172 		if thearch.SoftFloat && (isFloat[n.Type.Etype] || isComplex[n.Type.Etype]) {
   1173 			return true
   1174 		}
   1175 	case OLT, OEQ, ONE, OLE, OGE, OGT:
   1176 		if thearch.SoftFloat && (isFloat[n.Left.Type.Etype] || isComplex[n.Left.Type.Etype]) {
   1177 			return true
   1178 		}
   1179 	case OCONV:
   1180 		if thearch.SoftFloat && ((isFloat[n.Type.Etype] || isComplex[n.Type.Etype]) || (isFloat[n.Left.Type.Etype] || isComplex[n.Left.Type.Etype])) {
   1181 			return true
   1182 		}
   1183 	}
   1184 
   1185 	if n.Left != nil && n.Left.HasCall() {
   1186 		return true
   1187 	}
   1188 	if n.Right != nil && n.Right.HasCall() {
   1189 		return true
   1190 	}
   1191 	return false
   1192 }
   1193 
   1194 func badtype(op Op, tl *types.Type, tr *types.Type) {
   1195 	fmt_ := ""
   1196 	if tl != nil {
   1197 		fmt_ += fmt.Sprintf("\n\t%v", tl)
   1198 	}
   1199 	if tr != nil {
   1200 		fmt_ += fmt.Sprintf("\n\t%v", tr)
   1201 	}
   1202 
   1203 	// common mistake: *struct and *interface.
   1204 	if tl != nil && tr != nil && tl.IsPtr() && tr.IsPtr() {
   1205 		if tl.Elem().IsStruct() && tr.Elem().IsInterface() {
   1206 			fmt_ += "\n\t(*struct vs *interface)"
   1207 		} else if tl.Elem().IsInterface() && tr.Elem().IsStruct() {
   1208 			fmt_ += "\n\t(*interface vs *struct)"
   1209 		}
   1210 	}
   1211 
   1212 	s := fmt_
   1213 	yyerror("illegal types for operand: %v%s", op, s)
   1214 }
   1215 
   1216 // brcom returns !(op).
   1217 // For example, brcom(==) is !=.
   1218 func brcom(op Op) Op {
   1219 	switch op {
   1220 	case OEQ:
   1221 		return ONE
   1222 	case ONE:
   1223 		return OEQ
   1224 	case OLT:
   1225 		return OGE
   1226 	case OGT:
   1227 		return OLE
   1228 	case OLE:
   1229 		return OGT
   1230 	case OGE:
   1231 		return OLT
   1232 	}
   1233 	Fatalf("brcom: no com for %v\n", op)
   1234 	return op
   1235 }
   1236 
   1237 // brrev returns reverse(op).
   1238 // For example, Brrev(<) is >.
   1239 func brrev(op Op) Op {
   1240 	switch op {
   1241 	case OEQ:
   1242 		return OEQ
   1243 	case ONE:
   1244 		return ONE
   1245 	case OLT:
   1246 		return OGT
   1247 	case OGT:
   1248 		return OLT
   1249 	case OLE:
   1250 		return OGE
   1251 	case OGE:
   1252 		return OLE
   1253 	}
   1254 	Fatalf("brrev: no rev for %v\n", op)
   1255 	return op
   1256 }
   1257 
   1258 // return side effect-free n, appending side effects to init.
   1259 // result is assignable if n is.
   1260 func safeexpr(n *Node, init *Nodes) *Node {
   1261 	if n == nil {
   1262 		return nil
   1263 	}
   1264 
   1265 	if n.Ninit.Len() != 0 {
   1266 		walkstmtlist(n.Ninit.Slice())
   1267 		init.AppendNodes(&n.Ninit)
   1268 	}
   1269 
   1270 	switch n.Op {
   1271 	case ONAME, OLITERAL:
   1272 		return n
   1273 
   1274 	case ODOT, OLEN, OCAP:
   1275 		l := safeexpr(n.Left, init)
   1276 		if l == n.Left {
   1277 			return n
   1278 		}
   1279 		r := nod(OXXX, nil, nil)
   1280 		*r = *n
   1281 		r.Left = l
   1282 		r = typecheck(r, Erv)
   1283 		r = walkexpr(r, init)
   1284 		return r
   1285 
   1286 	case ODOTPTR, OIND:
   1287 		l := safeexpr(n.Left, init)
   1288 		if l == n.Left {
   1289 			return n
   1290 		}
   1291 		a := nod(OXXX, nil, nil)
   1292 		*a = *n
   1293 		a.Left = l
   1294 		a = walkexpr(a, init)
   1295 		return a
   1296 
   1297 	case OINDEX, OINDEXMAP:
   1298 		l := safeexpr(n.Left, init)
   1299 		r := safeexpr(n.Right, init)
   1300 		if l == n.Left && r == n.Right {
   1301 			return n
   1302 		}
   1303 		a := nod(OXXX, nil, nil)
   1304 		*a = *n
   1305 		a.Left = l
   1306 		a.Right = r
   1307 		a = walkexpr(a, init)
   1308 		return a
   1309 
   1310 	case OSTRUCTLIT, OARRAYLIT, OSLICELIT:
   1311 		if isStaticCompositeLiteral(n) {
   1312 			return n
   1313 		}
   1314 	}
   1315 
   1316 	// make a copy; must not be used as an lvalue
   1317 	if islvalue(n) {
   1318 		Fatalf("missing lvalue case in safeexpr: %v", n)
   1319 	}
   1320 	return cheapexpr(n, init)
   1321 }
   1322 
   1323 func copyexpr(n *Node, t *types.Type, init *Nodes) *Node {
   1324 	l := temp(t)
   1325 	a := nod(OAS, l, n)
   1326 	a = typecheck(a, Etop)
   1327 	a = walkexpr(a, init)
   1328 	init.Append(a)
   1329 	return l
   1330 }
   1331 
   1332 // return side-effect free and cheap n, appending side effects to init.
   1333 // result may not be assignable.
   1334 func cheapexpr(n *Node, init *Nodes) *Node {
   1335 	switch n.Op {
   1336 	case ONAME, OLITERAL:
   1337 		return n
   1338 	}
   1339 
   1340 	return copyexpr(n, n.Type, init)
   1341 }
   1342 
   1343 // Code to resolve elided DOTs in embedded types.
   1344 
   1345 // A Dlist stores a pointer to a TFIELD Type embedded within
   1346 // a TSTRUCT or TINTER Type.
   1347 type Dlist struct {
   1348 	field *types.Field
   1349 }
   1350 
   1351 // dotlist is used by adddot1 to record the path of embedded fields
   1352 // used to access a target field or method.
   1353 // Must be non-nil so that dotpath returns a non-nil slice even if d is zero.
   1354 var dotlist = make([]Dlist, 10)
   1355 
   1356 // lookdot0 returns the number of fields or methods named s associated
   1357 // with Type t. If exactly one exists, it will be returned in *save
   1358 // (if save is not nil).
   1359 func lookdot0(s *types.Sym, t *types.Type, save **types.Field, ignorecase bool) int {
   1360 	u := t
   1361 	if u.IsPtr() {
   1362 		u = u.Elem()
   1363 	}
   1364 
   1365 	c := 0
   1366 	if u.IsStruct() || u.IsInterface() {
   1367 		for _, f := range u.Fields().Slice() {
   1368 			if f.Sym == s || (ignorecase && f.Type.Etype == TFUNC && f.Type.Recv() != nil && strings.EqualFold(f.Sym.Name, s.Name)) {
   1369 				if save != nil {
   1370 					*save = f
   1371 				}
   1372 				c++
   1373 			}
   1374 		}
   1375 	}
   1376 
   1377 	u = methtype(t)
   1378 	if u != nil {
   1379 		for _, f := range u.Methods().Slice() {
   1380 			if f.Embedded == 0 && (f.Sym == s || (ignorecase && strings.EqualFold(f.Sym.Name, s.Name))) {
   1381 				if save != nil {
   1382 					*save = f
   1383 				}
   1384 				c++
   1385 			}
   1386 		}
   1387 	}
   1388 
   1389 	return c
   1390 }
   1391 
   1392 // adddot1 returns the number of fields or methods named s at depth d in Type t.
   1393 // If exactly one exists, it will be returned in *save (if save is not nil),
   1394 // and dotlist will contain the path of embedded fields traversed to find it,
   1395 // in reverse order. If none exist, more will indicate whether t contains any
   1396 // embedded fields at depth d, so callers can decide whether to retry at
   1397 // a greater depth.
   1398 func adddot1(s *types.Sym, t *types.Type, d int, save **types.Field, ignorecase bool) (c int, more bool) {
   1399 	if t.Recur() {
   1400 		return
   1401 	}
   1402 	t.SetRecur(true)
   1403 	defer t.SetRecur(false)
   1404 
   1405 	var u *types.Type
   1406 	d--
   1407 	if d < 0 {
   1408 		// We've reached our target depth. If t has any fields/methods
   1409 		// named s, then we're done. Otherwise, we still need to check
   1410 		// below for embedded fields.
   1411 		c = lookdot0(s, t, save, ignorecase)
   1412 		if c != 0 {
   1413 			return c, false
   1414 		}
   1415 	}
   1416 
   1417 	u = t
   1418 	if u.IsPtr() {
   1419 		u = u.Elem()
   1420 	}
   1421 	if !u.IsStruct() && !u.IsInterface() {
   1422 		return c, false
   1423 	}
   1424 
   1425 	for _, f := range u.Fields().Slice() {
   1426 		if f.Embedded == 0 || f.Sym == nil {
   1427 			continue
   1428 		}
   1429 		if d < 0 {
   1430 			// Found an embedded field at target depth.
   1431 			return c, true
   1432 		}
   1433 		a, more1 := adddot1(s, f.Type, d, save, ignorecase)
   1434 		if a != 0 && c == 0 {
   1435 			dotlist[d].field = f
   1436 		}
   1437 		c += a
   1438 		if more1 {
   1439 			more = true
   1440 		}
   1441 	}
   1442 
   1443 	return c, more
   1444 }
   1445 
   1446 // dotpath computes the unique shortest explicit selector path to fully qualify
   1447 // a selection expression x.f, where x is of type t and f is the symbol s.
   1448 // If no such path exists, dotpath returns nil.
   1449 // If there are multiple shortest paths to the same depth, ambig is true.
   1450 func dotpath(s *types.Sym, t *types.Type, save **types.Field, ignorecase bool) (path []Dlist, ambig bool) {
   1451 	// The embedding of types within structs imposes a tree structure onto
   1452 	// types: structs parent the types they embed, and types parent their
   1453 	// fields or methods. Our goal here is to find the shortest path to
   1454 	// a field or method named s in the subtree rooted at t. To accomplish
   1455 	// that, we iteratively perform depth-first searches of increasing depth
   1456 	// until we either find the named field/method or exhaust the tree.
   1457 	for d := 0; ; d++ {
   1458 		if d > len(dotlist) {
   1459 			dotlist = append(dotlist, Dlist{})
   1460 		}
   1461 		if c, more := adddot1(s, t, d, save, ignorecase); c == 1 {
   1462 			return dotlist[:d], false
   1463 		} else if c > 1 {
   1464 			return nil, true
   1465 		} else if !more {
   1466 			return nil, false
   1467 		}
   1468 	}
   1469 }
   1470 
   1471 // in T.field
   1472 // find missing fields that
   1473 // will give shortest unique addressing.
   1474 // modify the tree with missing type names.
   1475 func adddot(n *Node) *Node {
   1476 	n.Left = typecheck(n.Left, Etype|Erv)
   1477 	if n.Left.Diag() {
   1478 		n.SetDiag(true)
   1479 	}
   1480 	t := n.Left.Type
   1481 	if t == nil {
   1482 		return n
   1483 	}
   1484 
   1485 	if n.Left.Op == OTYPE {
   1486 		return n
   1487 	}
   1488 
   1489 	s := n.Sym
   1490 	if s == nil {
   1491 		return n
   1492 	}
   1493 
   1494 	switch path, ambig := dotpath(s, t, nil, false); {
   1495 	case path != nil:
   1496 		// rebuild elided dots
   1497 		for c := len(path) - 1; c >= 0; c-- {
   1498 			n.Left = nodSym(ODOT, n.Left, path[c].field.Sym)
   1499 			n.Left.SetImplicit(true)
   1500 		}
   1501 	case ambig:
   1502 		yyerror("ambiguous selector %v", n)
   1503 		n.Left = nil
   1504 	}
   1505 
   1506 	return n
   1507 }
   1508 
   1509 // code to help generate trampoline
   1510 // functions for methods on embedded
   1511 // subtypes.
   1512 // these are approx the same as
   1513 // the corresponding adddot routines
   1514 // except that they expect to be called
   1515 // with unique tasks and they return
   1516 // the actual methods.
   1517 type Symlink struct {
   1518 	field     *types.Field
   1519 	followptr bool
   1520 }
   1521 
   1522 var slist []Symlink
   1523 
   1524 func expand0(t *types.Type, followptr bool) {
   1525 	u := t
   1526 	if u.IsPtr() {
   1527 		followptr = true
   1528 		u = u.Elem()
   1529 	}
   1530 
   1531 	if u.IsInterface() {
   1532 		for _, f := range u.Fields().Slice() {
   1533 			if f.Sym.Uniq() {
   1534 				continue
   1535 			}
   1536 			f.Sym.SetUniq(true)
   1537 			slist = append(slist, Symlink{field: f, followptr: followptr})
   1538 		}
   1539 
   1540 		return
   1541 	}
   1542 
   1543 	u = methtype(t)
   1544 	if u != nil {
   1545 		for _, f := range u.Methods().Slice() {
   1546 			if f.Sym.Uniq() {
   1547 				continue
   1548 			}
   1549 			f.Sym.SetUniq(true)
   1550 			slist = append(slist, Symlink{field: f, followptr: followptr})
   1551 		}
   1552 	}
   1553 }
   1554 
   1555 func expand1(t *types.Type, top, followptr bool) {
   1556 	if t.Recur() {
   1557 		return
   1558 	}
   1559 	t.SetRecur(true)
   1560 
   1561 	if !top {
   1562 		expand0(t, followptr)
   1563 	}
   1564 
   1565 	u := t
   1566 	if u.IsPtr() {
   1567 		followptr = true
   1568 		u = u.Elem()
   1569 	}
   1570 
   1571 	if u.IsStruct() || u.IsInterface() {
   1572 		for _, f := range u.Fields().Slice() {
   1573 			if f.Embedded == 0 {
   1574 				continue
   1575 			}
   1576 			if f.Sym == nil {
   1577 				continue
   1578 			}
   1579 			expand1(f.Type, false, followptr)
   1580 		}
   1581 	}
   1582 
   1583 	t.SetRecur(false)
   1584 }
   1585 
   1586 func expandmeth(t *types.Type) {
   1587 	if t == nil || t.AllMethods().Len() != 0 {
   1588 		return
   1589 	}
   1590 
   1591 	// mark top-level method symbols
   1592 	// so that expand1 doesn't consider them.
   1593 	for _, f := range t.Methods().Slice() {
   1594 		f.Sym.SetUniq(true)
   1595 	}
   1596 
   1597 	// generate all reachable methods
   1598 	slist = slist[:0]
   1599 	expand1(t, true, false)
   1600 
   1601 	// check each method to be uniquely reachable
   1602 	var ms []*types.Field
   1603 	for i, sl := range slist {
   1604 		slist[i].field = nil
   1605 		sl.field.Sym.SetUniq(false)
   1606 
   1607 		var f *types.Field
   1608 		if path, _ := dotpath(sl.field.Sym, t, &f, false); path == nil {
   1609 			continue
   1610 		}
   1611 
   1612 		// dotpath may have dug out arbitrary fields, we only want methods.
   1613 		if f.Type.Etype != TFUNC || f.Type.Recv() == nil {
   1614 			continue
   1615 		}
   1616 
   1617 		// add it to the base type method list
   1618 		f = f.Copy()
   1619 		f.Embedded = 1 // needs a trampoline
   1620 		if sl.followptr {
   1621 			f.Embedded = 2
   1622 		}
   1623 		ms = append(ms, f)
   1624 	}
   1625 
   1626 	for _, f := range t.Methods().Slice() {
   1627 		f.Sym.SetUniq(false)
   1628 	}
   1629 
   1630 	ms = append(ms, t.Methods().Slice()...)
   1631 	t.AllMethods().Set(ms)
   1632 }
   1633 
   1634 // Given funarg struct list, return list of ODCLFIELD Node fn args.
   1635 func structargs(tl *types.Type, mustname bool) []*Node {
   1636 	var args []*Node
   1637 	gen := 0
   1638 	for _, t := range tl.Fields().Slice() {
   1639 		var n *Node
   1640 		if mustname && (t.Sym == nil || t.Sym.Name == "_") {
   1641 			// invent a name so that we can refer to it in the trampoline
   1642 			buf := fmt.Sprintf(".anon%d", gen)
   1643 			gen++
   1644 			n = newname(lookup(buf))
   1645 		} else if t.Sym != nil {
   1646 			n = newname(t.Sym)
   1647 		}
   1648 		a := nod(ODCLFIELD, n, typenod(t.Type))
   1649 		a.SetIsddd(t.Isddd())
   1650 		if n != nil {
   1651 			n.SetIsddd(t.Isddd())
   1652 		}
   1653 		args = append(args, a)
   1654 	}
   1655 
   1656 	return args
   1657 }
   1658 
   1659 // Generate a wrapper function to convert from
   1660 // a receiver of type T to a receiver of type U.
   1661 // That is,
   1662 //
   1663 //	func (t T) M() {
   1664 //		...
   1665 //	}
   1666 //
   1667 // already exists; this function generates
   1668 //
   1669 //	func (u U) M() {
   1670 //		u.M()
   1671 //	}
   1672 //
   1673 // where the types T and U are such that u.M() is valid
   1674 // and calls the T.M method.
   1675 // The resulting function is for use in method tables.
   1676 //
   1677 //	rcvr - U
   1678 //	method - M func (t T)(), a TFIELD type struct
   1679 //	newnam - the eventual mangled name of this function
   1680 func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym, iface bool) {
   1681 	if false && Debug['r'] != 0 {
   1682 		fmt.Printf("genwrapper rcvrtype=%v method=%v newnam=%v\n", rcvr, method, newnam)
   1683 	}
   1684 
   1685 	// Only generate (*T).M wrappers for T.M in T's own package.
   1686 	if rcvr.IsPtr() && rcvr.Elem() == method.Type.Recv().Type &&
   1687 		rcvr.Elem().Sym != nil && rcvr.Elem().Sym.Pkg != localpkg {
   1688 		return
   1689 	}
   1690 
   1691 	lineno = autogeneratedPos
   1692 
   1693 	dclcontext = PEXTERN
   1694 	types.Markdcl()
   1695 
   1696 	this := namedfield(".this", rcvr)
   1697 	this.Left.Name.Param.Ntype = this.Right
   1698 	in := structargs(method.Type.Params(), true)
   1699 	out := structargs(method.Type.Results(), false)
   1700 
   1701 	t := nod(OTFUNC, nil, nil)
   1702 	l := []*Node{this}
   1703 	if iface && rcvr.Width < int64(Widthptr) {
   1704 		// Building method for interface table and receiver
   1705 		// is smaller than the single pointer-sized word
   1706 		// that the interface call will pass in.
   1707 		// Add a dummy padding argument after the
   1708 		// receiver to make up the difference.
   1709 		tpad := types.NewArray(types.Types[TUINT8], int64(Widthptr)-rcvr.Width)
   1710 		pad := namedfield(".pad", tpad)
   1711 		l = append(l, pad)
   1712 	}
   1713 
   1714 	t.List.Set(append(l, in...))
   1715 	t.Rlist.Set(out)
   1716 
   1717 	fn := dclfunc(newnam, t)
   1718 	fn.Func.SetDupok(true)
   1719 	fn.Func.Nname.Sym.SetExported(true) // prevent export; see closure.go
   1720 
   1721 	// arg list
   1722 	var args []*Node
   1723 
   1724 	isddd := false
   1725 	for _, n := range in {
   1726 		args = append(args, n.Left)
   1727 		isddd = n.Left.Isddd()
   1728 	}
   1729 
   1730 	methodrcvr := method.Type.Recv().Type
   1731 
   1732 	// generate nil pointer check for better error
   1733 	if rcvr.IsPtr() && rcvr.Elem() == methodrcvr {
   1734 		// generating wrapper from *T to T.
   1735 		n := nod(OIF, nil, nil)
   1736 		n.Left = nod(OEQ, this.Left, nodnil())
   1737 		call := nod(OCALL, syslook("panicwrap"), nil)
   1738 		n.Nbody.Set1(call)
   1739 		fn.Nbody.Append(n)
   1740 	}
   1741 
   1742 	dot := adddot(nodSym(OXDOT, this.Left, method.Sym))
   1743 
   1744 	// generate call
   1745 	// It's not possible to use a tail call when dynamic linking on ppc64le. The
   1746 	// bad scenario is when a local call is made to the wrapper: the wrapper will
   1747 	// call the implementation, which might be in a different module and so set
   1748 	// the TOC to the appropriate value for that module. But if it returns
   1749 	// directly to the wrapper's caller, nothing will reset it to the correct
   1750 	// value for that function.
   1751 	if !instrumenting && rcvr.IsPtr() && methodrcvr.IsPtr() && method.Embedded != 0 && !isifacemethod(method.Type) && !(thearch.LinkArch.Name == "ppc64le" && Ctxt.Flag_dynlink) {
   1752 		// generate tail call: adjust pointer receiver and jump to embedded method.
   1753 		dot = dot.Left // skip final .M
   1754 		// TODO(mdempsky): Remove dependency on dotlist.
   1755 		if !dotlist[0].field.Type.IsPtr() {
   1756 			dot = nod(OADDR, dot, nil)
   1757 		}
   1758 		as := nod(OAS, this.Left, nod(OCONVNOP, dot, nil))
   1759 		as.Right.Type = rcvr
   1760 		fn.Nbody.Append(as)
   1761 		fn.Nbody.Append(nodSym(ORETJMP, nil, methodsym(method.Sym, methodrcvr, false)))
   1762 		// When tail-calling, we can't use a frame pointer.
   1763 		fn.Func.SetNoFramePointer(true)
   1764 	} else {
   1765 		fn.Func.SetWrapper(true) // ignore frame for panic+recover matching
   1766 		call := nod(OCALL, dot, nil)
   1767 		call.List.Set(args)
   1768 		call.SetIsddd(isddd)
   1769 		if method.Type.NumResults() > 0 {
   1770 			n := nod(ORETURN, nil, nil)
   1771 			n.List.Set1(call)
   1772 			call = n
   1773 		}
   1774 
   1775 		fn.Nbody.Append(call)
   1776 	}
   1777 
   1778 	if false && Debug['r'] != 0 {
   1779 		dumplist("genwrapper body", fn.Nbody)
   1780 	}
   1781 
   1782 	funcbody()
   1783 	Curfn = fn
   1784 	types.Popdcl()
   1785 	if debug_dclstack != 0 {
   1786 		testdclstack()
   1787 	}
   1788 
   1789 	// wrappers where T is anonymous (struct or interface) can be duplicated.
   1790 	if rcvr.IsStruct() || rcvr.IsInterface() || rcvr.IsPtr() && rcvr.Elem().IsStruct() {
   1791 		fn.Func.SetDupok(true)
   1792 	}
   1793 	fn = typecheck(fn, Etop)
   1794 	typecheckslice(fn.Nbody.Slice(), Etop)
   1795 
   1796 	inlcalls(fn)
   1797 	escAnalyze([]*Node{fn}, false)
   1798 
   1799 	Curfn = nil
   1800 	funccompile(fn)
   1801 }
   1802 
   1803 func hashmem(t *types.Type) *Node {
   1804 	sym := Runtimepkg.Lookup("memhash")
   1805 
   1806 	n := newname(sym)
   1807 	n.SetClass(PFUNC)
   1808 	tfn := nod(OTFUNC, nil, nil)
   1809 	tfn.List.Append(anonfield(types.NewPtr(t)))
   1810 	tfn.List.Append(anonfield(types.Types[TUINTPTR]))
   1811 	tfn.List.Append(anonfield(types.Types[TUINTPTR]))
   1812 	tfn.Rlist.Append(anonfield(types.Types[TUINTPTR]))
   1813 	tfn = typecheck(tfn, Etype)
   1814 	n.Type = tfn.Type
   1815 	return n
   1816 }
   1817 
   1818 func ifacelookdot(s *types.Sym, t *types.Type, ignorecase bool) (m *types.Field, followptr bool) {
   1819 	if t == nil {
   1820 		return nil, false
   1821 	}
   1822 
   1823 	path, ambig := dotpath(s, t, &m, ignorecase)
   1824 	if path == nil {
   1825 		if ambig {
   1826 			yyerror("%v.%v is ambiguous", t, s)
   1827 		}
   1828 		return nil, false
   1829 	}
   1830 
   1831 	for _, d := range path {
   1832 		if d.field.Type.IsPtr() {
   1833 			followptr = true
   1834 			break
   1835 		}
   1836 	}
   1837 
   1838 	if m.Type.Etype != TFUNC || m.Type.Recv() == nil {
   1839 		yyerror("%v.%v is a field, not a method", t, s)
   1840 		return nil, followptr
   1841 	}
   1842 
   1843 	return m, followptr
   1844 }
   1845 
   1846 func implements(t, iface *types.Type, m, samename **types.Field, ptr *int) bool {
   1847 	t0 := t
   1848 	if t == nil {
   1849 		return false
   1850 	}
   1851 
   1852 	// if this is too slow,
   1853 	// could sort these first
   1854 	// and then do one loop.
   1855 
   1856 	if t.IsInterface() {
   1857 	Outer:
   1858 		for _, im := range iface.Fields().Slice() {
   1859 			for _, tm := range t.Fields().Slice() {
   1860 				if tm.Sym == im.Sym {
   1861 					if eqtype(tm.Type, im.Type) {
   1862 						continue Outer
   1863 					}
   1864 					*m = im
   1865 					*samename = tm
   1866 					*ptr = 0
   1867 					return false
   1868 				}
   1869 			}
   1870 
   1871 			*m = im
   1872 			*samename = nil
   1873 			*ptr = 0
   1874 			return false
   1875 		}
   1876 
   1877 		return true
   1878 	}
   1879 
   1880 	t = methtype(t)
   1881 	if t != nil {
   1882 		expandmeth(t)
   1883 	}
   1884 	for _, im := range iface.Fields().Slice() {
   1885 		if im.Broke() {
   1886 			continue
   1887 		}
   1888 		tm, followptr := ifacelookdot(im.Sym, t, false)
   1889 		if tm == nil || tm.Nointerface() || !eqtype(tm.Type, im.Type) {
   1890 			if tm == nil {
   1891 				tm, followptr = ifacelookdot(im.Sym, t, true)
   1892 			}
   1893 			*m = im
   1894 			*samename = tm
   1895 			*ptr = 0
   1896 			return false
   1897 		}
   1898 
   1899 		// if pointer receiver in method,
   1900 		// the method does not exist for value types.
   1901 		rcvr := tm.Type.Recv().Type
   1902 
   1903 		if rcvr.IsPtr() && !t0.IsPtr() && !followptr && !isifacemethod(tm.Type) {
   1904 			if false && Debug['r'] != 0 {
   1905 				yyerror("interface pointer mismatch")
   1906 			}
   1907 
   1908 			*m = im
   1909 			*samename = nil
   1910 			*ptr = 1
   1911 			return false
   1912 		}
   1913 	}
   1914 
   1915 	// We're going to emit an OCONVIFACE.
   1916 	// Call itabname so that (t, iface)
   1917 	// gets added to itabs early, which allows
   1918 	// us to de-virtualize calls through this
   1919 	// type/interface pair later. See peekitabs in reflect.go
   1920 	if isdirectiface(t0) && !iface.IsEmptyInterface() {
   1921 		itabname(t0, iface)
   1922 	}
   1923 	return true
   1924 }
   1925 
   1926 func listtreecopy(l []*Node, pos src.XPos) []*Node {
   1927 	var out []*Node
   1928 	for _, n := range l {
   1929 		out = append(out, treecopy(n, pos))
   1930 	}
   1931 	return out
   1932 }
   1933 
   1934 func liststmt(l []*Node) *Node {
   1935 	n := nod(OBLOCK, nil, nil)
   1936 	n.List.Set(l)
   1937 	if len(l) != 0 {
   1938 		n.Pos = l[0].Pos
   1939 	}
   1940 	return n
   1941 }
   1942 
   1943 func (l Nodes) asblock() *Node {
   1944 	n := nod(OBLOCK, nil, nil)
   1945 	n.List = l
   1946 	if l.Len() != 0 {
   1947 		n.Pos = l.First().Pos
   1948 	}
   1949 	return n
   1950 }
   1951 
   1952 func ngotype(n *Node) *types.Sym {
   1953 	if n.Type != nil {
   1954 		return typenamesym(n.Type)
   1955 	}
   1956 	return nil
   1957 }
   1958 
   1959 // The result of addinit MUST be assigned back to n, e.g.
   1960 // 	n.Left = addinit(n.Left, init)
   1961 func addinit(n *Node, init []*Node) *Node {
   1962 	if len(init) == 0 {
   1963 		return n
   1964 	}
   1965 	if n.mayBeShared() {
   1966 		// Introduce OCONVNOP to hold init list.
   1967 		n = nod(OCONVNOP, n, nil)
   1968 		n.Type = n.Left.Type
   1969 		n.SetTypecheck(1)
   1970 	}
   1971 
   1972 	n.Ninit.Prepend(init...)
   1973 	n.SetHasCall(true)
   1974 	return n
   1975 }
   1976 
   1977 // The linker uses the magic symbol prefixes "go." and "type."
   1978 // Avoid potential confusion between import paths and symbols
   1979 // by rejecting these reserved imports for now. Also, people
   1980 // "can do weird things in GOPATH and we'd prefer they didn't
   1981 // do _that_ weird thing" (per rsc). See also #4257.
   1982 var reservedimports = []string{
   1983 	"go",
   1984 	"type",
   1985 }
   1986 
   1987 func isbadimport(path string, allowSpace bool) bool {
   1988 	if strings.Contains(path, "\x00") {
   1989 		yyerror("import path contains NUL")
   1990 		return true
   1991 	}
   1992 
   1993 	for _, ri := range reservedimports {
   1994 		if path == ri {
   1995 			yyerror("import path %q is reserved and cannot be used", path)
   1996 			return true
   1997 		}
   1998 	}
   1999 
   2000 	for _, r := range path {
   2001 		if r == utf8.RuneError {
   2002 			yyerror("import path contains invalid UTF-8 sequence: %q", path)
   2003 			return true
   2004 		}
   2005 
   2006 		if r < 0x20 || r == 0x7f {
   2007 			yyerror("import path contains control character: %q", path)
   2008 			return true
   2009 		}
   2010 
   2011 		if r == '\\' {
   2012 			yyerror("import path contains backslash; use slash: %q", path)
   2013 			return true
   2014 		}
   2015 
   2016 		if !allowSpace && unicode.IsSpace(r) {
   2017 			yyerror("import path contains space character: %q", path)
   2018 			return true
   2019 		}
   2020 
   2021 		if strings.ContainsRune("!\"#$%&'()*,:;<=>?[]^`{|}", r) {
   2022 			yyerror("import path contains invalid character '%c': %q", r, path)
   2023 			return true
   2024 		}
   2025 	}
   2026 
   2027 	return false
   2028 }
   2029 
   2030 func checknil(x *Node, init *Nodes) {
   2031 	x = walkexpr(x, nil) // caller has not done this yet
   2032 	if x.Type.IsInterface() {
   2033 		x = nod(OITAB, x, nil)
   2034 		x = typecheck(x, Erv)
   2035 	}
   2036 
   2037 	n := nod(OCHECKNIL, x, nil)
   2038 	n.SetTypecheck(1)
   2039 	init.Append(n)
   2040 }
   2041 
   2042 // Can this type be stored directly in an interface word?
   2043 // Yes, if the representation is a single pointer.
   2044 func isdirectiface(t *types.Type) bool {
   2045 	if t.Broke() {
   2046 		return false
   2047 	}
   2048 
   2049 	switch t.Etype {
   2050 	case TPTR32,
   2051 		TPTR64,
   2052 		TCHAN,
   2053 		TMAP,
   2054 		TFUNC,
   2055 		TUNSAFEPTR:
   2056 		return true
   2057 
   2058 	case TARRAY:
   2059 		// Array of 1 direct iface type can be direct.
   2060 		return t.NumElem() == 1 && isdirectiface(t.Elem())
   2061 
   2062 	case TSTRUCT:
   2063 		// Struct with 1 field of direct iface type can be direct.
   2064 		return t.NumFields() == 1 && isdirectiface(t.Field(0).Type)
   2065 	}
   2066 
   2067 	return false
   2068 }
   2069 
   2070 // itabType loads the _type field from a runtime.itab struct.
   2071 func itabType(itab *Node) *Node {
   2072 	typ := nodSym(ODOTPTR, itab, nil)
   2073 	typ.Type = types.NewPtr(types.Types[TUINT8])
   2074 	typ.SetTypecheck(1)
   2075 	typ.Xoffset = int64(Widthptr) // offset of _type in runtime.itab
   2076 	typ.SetBounded(true)          // guaranteed not to fault
   2077 	return typ
   2078 }
   2079 
   2080 // ifaceData loads the data field from an interface.
   2081 // The concrete type must be known to have type t.
   2082 // It follows the pointer if !isdirectiface(t).
   2083 func ifaceData(n *Node, t *types.Type) *Node {
   2084 	ptr := nodSym(OIDATA, n, nil)
   2085 	if isdirectiface(t) {
   2086 		ptr.Type = t
   2087 		ptr.SetTypecheck(1)
   2088 		return ptr
   2089 	}
   2090 	ptr.Type = types.NewPtr(t)
   2091 	ptr.SetBounded(true)
   2092 	ptr.SetTypecheck(1)
   2093 	ind := nod(OIND, ptr, nil)
   2094 	ind.Type = t
   2095 	ind.SetTypecheck(1)
   2096 	return ind
   2097 }
   2098