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