...

Source file src/pkg/cmd/compile/internal/gc/subr.go

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

View as plain text