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	"fmt"
12	"math"
13	"strings"
14)
15
16const (
17	Etop      = 1 << iota // evaluated at statement level
18	Erv                   // evaluated in value context
19	Etype                 // evaluated in type context
20	Ecall                 // call-only expressions are ok
21	Efnstruct             // multivalue function returns are ok
22	Easgn                 // assigning to expression
23	Ecomplit              // type in composite literal
24)
25
26// type checks the whole tree of an expression.
27// calculates expression types.
28// evaluates compile time constants.
29// marks variables that escape the local frame.
30// rewrites n.Op to be more specific in some cases.
31
32var typecheckdefstack []*Node
33
34// resolve ONONAME to definition, if any.
35func resolve(n *Node) *Node {
36	if n != nil && n.Op == ONONAME && n.Sym != nil {
37		r := asNode(n.Sym.Def)
38		if r != nil {
39			if r.Op != OIOTA {
40				n = r
41			} else if len(typecheckdefstack) > 0 {
42				x := typecheckdefstack[len(typecheckdefstack)-1]
43				if x.Op == OLITERAL {
44					n = nodintconst(x.Iota())
45				}
46			}
47		}
48	}
49
50	return n
51}
52
53func typecheckslice(l []*Node, top int) {
54	for i := range l {
55		l[i] = typecheck(l[i], top)
56	}
57}
58
59var _typekind = []string{
60	TINT:        "int",
61	TUINT:       "uint",
62	TINT8:       "int8",
63	TUINT8:      "uint8",
64	TINT16:      "int16",
65	TUINT16:     "uint16",
66	TINT32:      "int32",
67	TUINT32:     "uint32",
68	TINT64:      "int64",
69	TUINT64:     "uint64",
70	TUINTPTR:    "uintptr",
71	TCOMPLEX64:  "complex64",
72	TCOMPLEX128: "complex128",
73	TFLOAT32:    "float32",
74	TFLOAT64:    "float64",
75	TBOOL:       "bool",
76	TSTRING:     "string",
77	TPTR32:      "pointer",
78	TPTR64:      "pointer",
79	TUNSAFEPTR:  "unsafe.Pointer",
80	TSTRUCT:     "struct",
81	TINTER:      "interface",
82	TCHAN:       "chan",
83	TMAP:        "map",
84	TARRAY:      "array",
85	TSLICE:      "slice",
86	TFUNC:       "func",
87	TNIL:        "nil",
88	TIDEAL:      "untyped number",
89}
90
91func typekind(t *types.Type) string {
92	if t.IsSlice() {
93		return "slice"
94	}
95	et := t.Etype
96	if int(et) < len(_typekind) {
97		s := _typekind[et]
98		if s != "" {
99			return s
100		}
101	}
102	return fmt.Sprintf("etype=%d", et)
103}
104
105// sprint_depchain prints a dependency chain of nodes into trace.
106// It is used by typecheck in the case of OLITERAL nodes
107// to print constant definition loops.
108func sprint_depchain(trace *string, stack []*Node, cur *Node, first *Node) {
109	for i := len(stack) - 1; i >= 0; i-- {
110		if n := stack[i]; n.Op == cur.Op {
111			if n != first {
112				sprint_depchain(trace, stack[:i], n, first)
113			}
114			*trace += fmt.Sprintf("\n\t%v: %v uses %v", n.Line(), n, cur)
115			return
116		}
117	}
118}
119
120var typecheck_tcstack []*Node
121
122// typecheck type checks node n.
123// The result of typecheck MUST be assigned back to n, e.g.
124// 	n.Left = typecheck(n.Left, top)
125func typecheck(n *Node, top int) *Node {
126	// cannot type check until all the source has been parsed
127	if !typecheckok {
128		Fatalf("early typecheck")
129	}
130
131	if n == nil {
132		return nil
133	}
134
135	lno := setlineno(n)
136
137	// Skip over parens.
138	for n.Op == OPAREN {
139		n = n.Left
140	}
141
142	// Resolve definition of name and value of iota lazily.
143	n = resolve(n)
144
145	// Skip typecheck if already done.
146	// But re-typecheck ONAME/OTYPE/OLITERAL/OPACK node in case context has changed.
147	if n.Typecheck() == 1 {
148		switch n.Op {
149		case ONAME, OTYPE, OLITERAL, OPACK:
150			break
151
152		default:
153			lineno = lno
154			return n
155		}
156	}
157
158	if n.Typecheck() == 2 {
159		// Typechecking loop. Trying printing a meaningful message,
160		// otherwise a stack trace of typechecking.
161		switch n.Op {
162		// We can already diagnose variables used as types.
163		case ONAME:
164			if top&(Erv|Etype) == Etype {
165				yyerror("%v is not a type", n)
166			}
167
168		case OTYPE:
169			if top&Etype == Etype {
170				var trace string
171				sprint_depchain(&trace, typecheck_tcstack, n, n)
172				yyerrorl(n.Pos, "invalid recursive type alias %v%s", n, trace)
173			}
174
175		case OLITERAL:
176			if top&(Erv|Etype) == Etype {
177				yyerror("%v is not a type", n)
178				break
179			}
180			var trace string
181			sprint_depchain(&trace, typecheck_tcstack, n, n)
182			yyerrorl(n.Pos, "constant definition loop%s", trace)
183		}
184
185		if nsavederrors+nerrors == 0 {
186			var trace string
187			for i := len(typecheck_tcstack) - 1; i >= 0; i-- {
188				x := typecheck_tcstack[i]
189				trace += fmt.Sprintf("\n\t%v %v", x.Line(), x)
190			}
191			yyerror("typechecking loop involving %v%s", n, trace)
192		}
193
194		lineno = lno
195		return n
196	}
197
198	n.SetTypecheck(2)
199
200	typecheck_tcstack = append(typecheck_tcstack, n)
201	n = typecheck1(n, top)
202
203	n.SetTypecheck(1)
204
205	last := len(typecheck_tcstack) - 1
206	typecheck_tcstack[last] = nil
207	typecheck_tcstack = typecheck_tcstack[:last]
208
209	lineno = lno
210	return n
211}
212
213// does n contain a call or receive operation?
214func callrecv(n *Node) bool {
215	if n == nil {
216		return false
217	}
218
219	switch n.Op {
220	case OCALL,
221		OCALLMETH,
222		OCALLINTER,
223		OCALLFUNC,
224		ORECV,
225		OCAP,
226		OLEN,
227		OCOPY,
228		ONEW,
229		OAPPEND,
230		ODELETE:
231		return true
232	}
233
234	return callrecv(n.Left) || callrecv(n.Right) || callrecvlist(n.Ninit) || callrecvlist(n.Nbody) || callrecvlist(n.List) || callrecvlist(n.Rlist)
235}
236
237func callrecvlist(l Nodes) bool {
238	for _, n := range l.Slice() {
239		if callrecv(n) {
240			return true
241		}
242	}
243	return false
244}
245
246// indexlit implements typechecking of untyped values as
247// array/slice indexes. It is equivalent to defaultlit
248// except for constants of numerical kind, which are acceptable
249// whenever they can be represented by a value of type int.
250// The result of indexlit MUST be assigned back to n, e.g.
251// 	n.Left = indexlit(n.Left)
252func indexlit(n *Node) *Node {
253	if n == nil || !n.Type.IsUntyped() {
254		return n
255	}
256	switch consttype(n) {
257	case CTINT, CTRUNE, CTFLT, CTCPLX:
258		n = defaultlit(n, types.Types[TINT])
259	}
260
261	n = defaultlit(n, nil)
262	return n
263}
264
265// The result of typecheck1 MUST be assigned back to n, e.g.
266// 	n.Left = typecheck1(n.Left, top)
267func typecheck1(n *Node, top int) *Node {
268	switch n.Op {
269	case OXDOT, ODOT, ODOTPTR, ODOTMETH, ODOTINTER:
270		// n.Sym is a field/method name, not a variable.
271	default:
272		if n.Sym != nil {
273			if n.Op == ONAME && n.Etype != 0 && top&Ecall == 0 {
274				yyerror("use of builtin %v not in function call", n.Sym)
275				n.Type = nil
276				return n
277			}
278
279			typecheckdef(n)
280			if n.Op == ONONAME {
281				n.Type = nil
282				return n
283			}
284		}
285	}
286
287	ok := 0
288OpSwitch:
289	switch n.Op {
290	// until typecheck is complete, do nothing.
291	default:
292		Dump("typecheck", n)
293
294		Fatalf("typecheck %v", n.Op)
295
296	// names
297	case OLITERAL:
298		ok |= Erv
299
300		if n.Type == nil && n.Val().Ctype() == CTSTR {
301			n.Type = types.Idealstring
302		}
303		break OpSwitch
304
305	case ONONAME:
306		ok |= Erv
307		break OpSwitch
308
309	case ONAME:
310		if n.Name.Decldepth == 0 {
311			n.Name.Decldepth = decldepth
312		}
313		if n.Etype != 0 {
314			ok |= Ecall
315			break OpSwitch
316		}
317
318		if top&Easgn == 0 {
319			// not a write to the variable
320			if isblank(n) {
321				yyerror("cannot use _ as value")
322				n.Type = nil
323				return n
324			}
325
326			n.Name.SetUsed(true)
327		}
328
329		ok |= Erv
330		break OpSwitch
331
332	case OPACK:
333		yyerror("use of package %v without selector", n.Sym)
334		n.Type = nil
335		return n
336
337	case ODDD:
338		break
339
340	// types (OIND is with exprs)
341	case OTYPE:
342		ok |= Etype
343
344		if n.Type == nil {
345			return n
346		}
347
348	case OTARRAY:
349		ok |= Etype
350		r := typecheck(n.Right, Etype)
351		if r.Type == nil {
352			n.Type = nil
353			return n
354		}
355
356		var t *types.Type
357		if n.Left == nil {
358			t = types.NewSlice(r.Type)
359		} else if n.Left.Op == ODDD {
360			if top&Ecomplit == 0 {
361				if !n.Diag() {
362					n.SetDiag(true)
363					yyerror("use of [...] array outside of array literal")
364				}
365				n.Type = nil
366				return n
367			}
368			t = types.NewDDDArray(r.Type)
369		} else {
370			n.Left = indexlit(typecheck(n.Left, Erv))
371			l := n.Left
372			if consttype(l) != CTINT {
373				switch {
374				case l.Type == nil:
375					// Error already reported elsewhere.
376				case l.Type.IsInteger() && l.Op != OLITERAL:
377					yyerror("non-constant array bound %v", l)
378				default:
379					yyerror("invalid array bound %v", l)
380				}
381				n.Type = nil
382				return n
383			}
384
385			v := l.Val()
386			if doesoverflow(v, types.Types[TINT]) {
387				yyerror("array bound is too large")
388				n.Type = nil
389				return n
390			}
391
392			bound := v.U.(*Mpint).Int64()
393			if bound < 0 {
394				yyerror("array bound must be non-negative")
395				n.Type = nil
396				return n
397			}
398			t = types.NewArray(r.Type, bound)
399		}
400
401		n.Op = OTYPE
402		n.Type = t
403		n.Left = nil
404		n.Right = nil
405		if !t.IsDDDArray() {
406			checkwidth(t)
407		}
408
409	case OTMAP:
410		ok |= Etype
411		n.Left = typecheck(n.Left, Etype)
412		n.Right = typecheck(n.Right, Etype)
413		l := n.Left
414		r := n.Right
415		if l.Type == nil || r.Type == nil {
416			n.Type = nil
417			return n
418		}
419		if l.Type.NotInHeap() {
420			yyerror("go:notinheap map key not allowed")
421		}
422		if r.Type.NotInHeap() {
423			yyerror("go:notinheap map value not allowed")
424		}
425		n.Op = OTYPE
426		n.Type = types.NewMap(l.Type, r.Type)
427
428		// map key validation
429		alg, bad := algtype1(l.Type)
430		if alg == ANOEQ {
431			if bad.Etype == TFORW {
432				// queue check for map until all the types are done settling.
433				mapqueue = append(mapqueue, mapqueueval{l, n.Pos})
434			} else if bad.Etype != TANY {
435				// no need to queue, key is already bad
436				yyerror("invalid map key type %v", l.Type)
437			}
438		}
439		n.Left = nil
440		n.Right = nil
441
442	case OTCHAN:
443		ok |= Etype
444		n.Left = typecheck(n.Left, Etype)
445		l := n.Left
446		if l.Type == nil {
447			n.Type = nil
448			return n
449		}
450		if l.Type.NotInHeap() {
451			yyerror("chan of go:notinheap type not allowed")
452		}
453		t := types.NewChan(l.Type, types.ChanDir(n.Etype)) // TODO(marvin): Fix Node.EType type union.
454		n.Op = OTYPE
455		n.Type = t
456		n.Left = nil
457		n.Etype = 0
458
459	case OTSTRUCT:
460		ok |= Etype
461		n.Op = OTYPE
462		n.Type = tostruct(n.List.Slice())
463		if n.Type == nil || n.Type.Broke() {
464			n.Type = nil
465			return n
466		}
467		n.List.Set(nil)
468
469	case OTINTER:
470		ok |= Etype
471		n.Op = OTYPE
472		n.Type = tointerface(n.List.Slice())
473		if n.Type == nil {
474			return n
475		}
476
477	case OTFUNC:
478		ok |= Etype
479		n.Op = OTYPE
480		n.Type = functype(n.Left, n.List.Slice(), n.Rlist.Slice())
481		if n.Type == nil {
482			return n
483		}
484		n.Left = nil
485		n.List.Set(nil)
486		n.Rlist.Set(nil)
487
488	// type or expr
489	case OIND:
490		n.Left = typecheck(n.Left, Erv|Etype|top&Ecomplit)
491		l := n.Left
492		t := l.Type
493		if t == nil {
494			n.Type = nil
495			return n
496		}
497		if l.Op == OTYPE {
498			ok |= Etype
499			n.Op = OTYPE
500			n.Type = types.NewPtr(l.Type)
501			// Ensure l.Type gets dowidth'd for the backend. Issue 20174.
502			// Don't checkwidth [...] arrays, though, since they
503			// will be replaced by concrete-sized arrays. Issue 20333.
504			if !l.Type.IsDDDArray() {
505				checkwidth(l.Type)
506			}
507			n.Left = nil
508			break OpSwitch
509		}
510
511		if !t.IsPtr() {
512			if top&(Erv|Etop) != 0 {
513				yyerror("invalid indirect of %L", n.Left)
514				n.Type = nil
515				return n
516			}
517
518			break OpSwitch
519		}
520
521		ok |= Erv
522		n.Type = t.Elem()
523		break OpSwitch
524
525	// arithmetic exprs
526	case OASOP,
527		OADD,
528		OAND,
529		OANDAND,
530		OANDNOT,
531		ODIV,
532		OEQ,
533		OGE,
534		OGT,
535		OLE,
536		OLT,
537		OLSH,
538		ORSH,
539		OMOD,
540		OMUL,
541		ONE,
542		OOR,
543		OOROR,
544		OSUB,
545		OXOR:
546		var l *Node
547		var op Op
548		var r *Node
549		if n.Op == OASOP {
550			ok |= Etop
551			n.Left = typecheck(n.Left, Erv)
552			n.Right = typecheck(n.Right, Erv)
553			l = n.Left
554			r = n.Right
555			checkassign(n, n.Left)
556			if l.Type == nil || r.Type == nil {
557				n.Type = nil
558				return n
559			}
560			if n.Implicit() && !okforarith[l.Type.Etype] {
561				yyerror("invalid operation: %v (non-numeric type %v)", n, l.Type)
562				n.Type = nil
563				return n
564			}
565			// TODO(marvin): Fix Node.EType type union.
566			op = Op(n.Etype)
567		} else {
568			ok |= Erv
569			n.Left = typecheck(n.Left, Erv)
570			n.Right = typecheck(n.Right, Erv)
571			l = n.Left
572			r = n.Right
573			if l.Type == nil || r.Type == nil {
574				n.Type = nil
575				return n
576			}
577			op = n.Op
578		}
579		if op == OLSH || op == ORSH {
580			r = defaultlit(r, types.Types[TUINT])
581			n.Right = r
582			t := r.Type
583			if !t.IsInteger() || t.IsSigned() {
584				yyerror("invalid operation: %v (shift count type %v, must be unsigned integer)", n, r.Type)
585				n.Type = nil
586				return n
587			}
588
589			t = l.Type
590			if t != nil && t.Etype != TIDEAL && !t.IsInteger() {
591				yyerror("invalid operation: %v (shift of type %v)", n, t)
592				n.Type = nil
593				return n
594			}
595
596			// no defaultlit for left
597			// the outer context gives the type
598			n.Type = l.Type
599
600			break OpSwitch
601		}
602
603		// ideal mixed with non-ideal
604		l, r = defaultlit2(l, r, false)
605
606		n.Left = l
607		n.Right = r
608		if l.Type == nil || r.Type == nil {
609			n.Type = nil
610			return n
611		}
612		t := l.Type
613		if t.Etype == TIDEAL {
614			t = r.Type
615		}
616		et := t.Etype
617		if et == TIDEAL {
618			et = TINT
619		}
620		var aop Op = OXXX
621		if iscmp[n.Op] && t.Etype != TIDEAL && !eqtype(l.Type, r.Type) {
622			// comparison is okay as long as one side is
623			// assignable to the other.  convert so they have
624			// the same type.
625			//
626			// the only conversion that isn't a no-op is concrete == interface.
627			// in that case, check comparability of the concrete type.
628			// The conversion allocates, so only do it if the concrete type is huge.
629			if r.Type.Etype != TBLANK {
630				aop = assignop(l.Type, r.Type, nil)
631				if aop != 0 {
632					if r.Type.IsInterface() && !l.Type.IsInterface() && !IsComparable(l.Type) {
633						yyerror("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(l.Type))
634						n.Type = nil
635						return n
636					}
637
638					dowidth(l.Type)
639					if r.Type.IsInterface() == l.Type.IsInterface() || l.Type.Width >= 1<<16 {
640						l = nod(aop, l, nil)
641						l.Type = r.Type
642						l.SetTypecheck(1)
643						n.Left = l
644					}
645
646					t = r.Type
647					goto converted
648				}
649			}
650
651			if l.Type.Etype != TBLANK {
652				aop = assignop(r.Type, l.Type, nil)
653				if aop != 0 {
654					if l.Type.IsInterface() && !r.Type.IsInterface() && !IsComparable(r.Type) {
655						yyerror("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(r.Type))
656						n.Type = nil
657						return n
658					}
659
660					dowidth(r.Type)
661					if r.Type.IsInterface() == l.Type.IsInterface() || r.Type.Width >= 1<<16 {
662						r = nod(aop, r, nil)
663						r.Type = l.Type
664						r.SetTypecheck(1)
665						n.Right = r
666					}
667
668					t = l.Type
669				}
670			}
671
672		converted:
673			et = t.Etype
674		}
675
676		if t.Etype != TIDEAL && !eqtype(l.Type, r.Type) {
677			l, r = defaultlit2(l, r, true)
678			if r.Type.IsInterface() == l.Type.IsInterface() || aop == 0 {
679				yyerror("invalid operation: %v (mismatched types %v and %v)", n, l.Type, r.Type)
680				n.Type = nil
681				return n
682			}
683		}
684
685		if !okfor[op][et] {
686			yyerror("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(t))
687			n.Type = nil
688			return n
689		}
690
691		// okfor allows any array == array, map == map, func == func.
692		// restrict to slice/map/func == nil and nil == slice/map/func.
693		if l.Type.IsArray() && !IsComparable(l.Type) {
694			yyerror("invalid operation: %v (%v cannot be compared)", n, l.Type)
695			n.Type = nil
696			return n
697		}
698
699		if l.Type.IsSlice() && !isnil(l) && !isnil(r) {
700			yyerror("invalid operation: %v (slice can only be compared to nil)", n)
701			n.Type = nil
702			return n
703		}
704
705		if l.Type.IsMap() && !isnil(l) && !isnil(r) {
706			yyerror("invalid operation: %v (map can only be compared to nil)", n)
707			n.Type = nil
708			return n
709		}
710
711		if l.Type.Etype == TFUNC && !isnil(l) && !isnil(r) {
712			yyerror("invalid operation: %v (func can only be compared to nil)", n)
713			n.Type = nil
714			return n
715		}
716
717		if l.Type.IsStruct() {
718			if f := IncomparableField(l.Type); f != nil {
719				yyerror("invalid operation: %v (struct containing %v cannot be compared)", n, f.Type)
720				n.Type = nil
721				return n
722			}
723		}
724
725		t = l.Type
726		if iscmp[n.Op] {
727			evconst(n)
728			t = types.Idealbool
729			if n.Op != OLITERAL {
730				l, r = defaultlit2(l, r, true)
731				n.Left = l
732				n.Right = r
733			}
734		}
735
736		if et == TSTRING {
737			if iscmp[n.Op] {
738				// TODO(marvin): Fix Node.EType type union.
739				n.Etype = types.EType(n.Op)
740				n.Op = OCMPSTR
741			} else if n.Op == OADD {
742				// create OADDSTR node with list of strings in x + y + z + (w + v) + ...
743				n.Op = OADDSTR
744
745				if l.Op == OADDSTR {
746					n.List.Set(l.List.Slice())
747				} else {
748					n.List.Set1(l)
749				}
750				if r.Op == OADDSTR {
751					n.List.AppendNodes(&r.List)
752				} else {
753					n.List.Append(r)
754				}
755				n.Left = nil
756				n.Right = nil
757			}
758		}
759
760		if et == TINTER {
761			if l.Op == OLITERAL && l.Val().Ctype() == CTNIL {
762				// swap for back end
763				n.Left = r
764
765				n.Right = l
766			} else if r.Op == OLITERAL && r.Val().Ctype() == CTNIL {
767			} else // leave alone for back end
768			if r.Type.IsInterface() == l.Type.IsInterface() {
769				// TODO(marvin): Fix Node.EType type union.
770				n.Etype = types.EType(n.Op)
771				n.Op = OCMPIFACE
772			}
773		}
774
775		if (op == ODIV || op == OMOD) && Isconst(r, CTINT) {
776			if r.Val().U.(*Mpint).CmpInt64(0) == 0 {
777				yyerror("division by zero")
778				n.Type = nil
779				return n
780			}
781		}
782
783		n.Type = t
784		break OpSwitch
785
786	case OCOM, OMINUS, ONOT, OPLUS:
787		ok |= Erv
788		n.Left = typecheck(n.Left, Erv)
789		l := n.Left
790		t := l.Type
791		if t == nil {
792			n.Type = nil
793			return n
794		}
795		if !okfor[n.Op][t.Etype] {
796			yyerror("invalid operation: %v %v", n.Op, t)
797			n.Type = nil
798			return n
799		}
800
801		n.Type = t
802		break OpSwitch
803
804	// exprs
805	case OADDR:
806		ok |= Erv
807
808		n.Left = typecheck(n.Left, Erv)
809		if n.Left.Type == nil {
810			n.Type = nil
811			return n
812		}
813		checklvalue(n.Left, "take the address of")
814		r := outervalue(n.Left)
815		var l *Node
816		for l = n.Left; l != r; l = l.Left {
817			l.SetAddrtaken(true)
818			if l.IsClosureVar() && !capturevarscomplete {
819				// Mark the original variable as Addrtaken so that capturevars
820				// knows not to pass it by value.
821				// But if the capturevars phase is complete, don't touch it,
822				// in case l.Name's containing function has not yet been compiled.
823				l.Name.Defn.SetAddrtaken(true)
824			}
825		}
826
827		if l.Orig != l && l.Op == ONAME {
828			Fatalf("found non-orig name node %v", l)
829		}
830		l.SetAddrtaken(true)
831		if l.IsClosureVar() && !capturevarscomplete {
832			// See comments above about closure variables.
833			l.Name.Defn.SetAddrtaken(true)
834		}
835		n.Left = defaultlit(n.Left, nil)
836		l = n.Left
837		t := l.Type
838		if t == nil {
839			n.Type = nil
840			return n
841		}
842		n.Type = types.NewPtr(t)
843		break OpSwitch
844
845	case OCOMPLIT:
846		ok |= Erv
847		n = typecheckcomplit(n)
848		if n.Type == nil {
849			return n
850		}
851		break OpSwitch
852
853	case OXDOT, ODOT:
854		if n.Op == OXDOT {
855			n = adddot(n)
856			n.Op = ODOT
857			if n.Left == nil {
858				n.Type = nil
859				return n
860			}
861		}
862
863		n.Left = typecheck(n.Left, Erv|Etype)
864
865		n.Left = defaultlit(n.Left, nil)
866
867		t := n.Left.Type
868		if t == nil {
869			adderrorname(n)
870			n.Type = nil
871			return n
872		}
873
874		s := n.Sym
875
876		if n.Left.Op == OTYPE {
877			if !looktypedot(n, t, 0) {
878				if looktypedot(n, t, 1) {
879					yyerror("%v undefined (cannot refer to unexported method %v)", n, n.Sym)
880				} else {
881					yyerror("%v undefined (type %v has no method %v)", n, t, n.Sym)
882				}
883				n.Type = nil
884				return n
885			}
886
887			if n.Type.Etype != TFUNC || !n.IsMethod() {
888				yyerror("type %v has no method %S", n.Left.Type, n.Sym)
889				n.Type = nil
890				return n
891			}
892
893			n.Op = ONAME
894			if n.Name == nil {
895				n.Name = new(Name)
896			}
897			n.Right = newname(n.Sym)
898			n.Type = methodfunc(n.Type, n.Left.Type)
899			n.Xoffset = 0
900			n.SetClass(PFUNC)
901			ok = Erv
902			break OpSwitch
903		}
904
905		if t.IsPtr() && !t.Elem().IsInterface() {
906			t = t.Elem()
907			if t == nil {
908				n.Type = nil
909				return n
910			}
911			n.Op = ODOTPTR
912			checkwidth(t)
913		}
914
915		if n.Sym.IsBlank() {
916			yyerror("cannot refer to blank field or method")
917			n.Type = nil
918			return n
919		}
920
921		if lookdot(n, t, 0) == nil {
922			// Legitimate field or method lookup failed, try to explain the error
923			switch {
924			case t.IsEmptyInterface():
925				yyerror("%v undefined (type %v is interface with no methods)", n, n.Left.Type)
926
927			case t.IsPtr() && t.Elem().IsInterface():
928				// Pointer to interface is almost always a mistake.
929				yyerror("%v undefined (type %v is pointer to interface, not interface)", n, n.Left.Type)
930
931			case lookdot(n, t, 1) != nil:
932				// Field or method matches by name, but it is not exported.
933				yyerror("%v undefined (cannot refer to unexported field or method %v)", n, n.Sym)
934
935			default:
936				if mt := lookdot(n, t, 2); mt != nil { // Case-insensitive lookup.
937					yyerror("%v undefined (type %v has no field or method %v, but does have %v)", n, n.Left.Type, n.Sym, mt.Sym)
938				} else {
939					yyerror("%v undefined (type %v has no field or method %v)", n, n.Left.Type, n.Sym)
940				}
941			}
942			n.Type = nil
943			return n
944		}
945
946		switch n.Op {
947		case ODOTINTER, ODOTMETH:
948			if top&Ecall != 0 {
949				ok |= Ecall
950			} else {
951				typecheckpartialcall(n, s)
952				ok |= Erv
953			}
954
955		default:
956			ok |= Erv
957		}
958
959		break OpSwitch
960
961	case ODOTTYPE:
962		ok |= Erv
963		n.Left = typecheck(n.Left, Erv)
964		n.Left = defaultlit(n.Left, nil)
965		l := n.Left
966		t := l.Type
967		if t == nil {
968			n.Type = nil
969			return n
970		}
971		if !t.IsInterface() {
972			yyerror("invalid type assertion: %v (non-interface type %v on left)", n, t)
973			n.Type = nil
974			return n
975		}
976
977		if n.Right != nil {
978			n.Right = typecheck(n.Right, Etype)
979			n.Type = n.Right.Type
980			n.Right = nil
981			if n.Type == nil {
982				return n
983			}
984		}
985
986		if n.Type != nil && !n.Type.IsInterface() {
987			var missing, have *types.Field
988			var ptr int
989			if !implements(n.Type, t, &missing, &have, &ptr) {
990				if have != nil && have.Sym == missing.Sym {
991					yyerror("impossible type assertion:\n\t%v does not implement %v (wrong type for %v method)\n"+
992						"\t\thave %v%0S\n\t\twant %v%0S", n.Type, t, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
993				} else if ptr != 0 {
994					yyerror("impossible type assertion:\n\t%v does not implement %v (%v method has pointer receiver)", n.Type, t, missing.Sym)
995				} else if have != nil {
996					yyerror("impossible type assertion:\n\t%v does not implement %v (missing %v method)\n"+
997						"\t\thave %v%0S\n\t\twant %v%0S", n.Type, t, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
998				} else {
999					yyerror("impossible type assertion:\n\t%v does not implement %v (missing %v method)", n.Type, t, missing.Sym)
1000				}
1001				n.Type = nil
1002				return n
1003			}
1004		}
1005
1006		break OpSwitch
1007
1008	case OINDEX:
1009		ok |= Erv
1010		n.Left = typecheck(n.Left, Erv)
1011		n.Left = defaultlit(n.Left, nil)
1012		n.Left = implicitstar(n.Left)
1013		l := n.Left
1014		n.Right = typecheck(n.Right, Erv)
1015		r := n.Right
1016		t := l.Type
1017		if t == nil || r.Type == nil {
1018			n.Type = nil
1019			return n
1020		}
1021		switch t.Etype {
1022		default:
1023			yyerror("invalid operation: %v (type %v does not support indexing)", n, t)
1024			n.Type = nil
1025			return n
1026
1027		case TSTRING, TARRAY, TSLICE:
1028			n.Right = indexlit(n.Right)
1029			if t.IsString() {
1030				n.Type = types.Bytetype
1031			} else {
1032				n.Type = t.Elem()
1033			}
1034			why := "string"
1035			if t.IsArray() {
1036				why = "array"
1037			} else if t.IsSlice() {
1038				why = "slice"
1039			}
1040
1041			if n.Right.Type != nil && !n.Right.Type.IsInteger() {
1042				yyerror("non-integer %s index %v", why, n.Right)
1043				break
1044			}
1045
1046			if !n.Bounded() && Isconst(n.Right, CTINT) {
1047				x := n.Right.Int64()
1048				if x < 0 {
1049					yyerror("invalid %s index %v (index must be non-negative)", why, n.Right)
1050				} else if t.IsArray() && x >= t.NumElem() {
1051					yyerror("invalid array index %v (out of bounds for %d-element array)", n.Right, t.NumElem())
1052				} else if Isconst(n.Left, CTSTR) && x >= int64(len(n.Left.Val().U.(string))) {
1053					yyerror("invalid string index %v (out of bounds for %d-byte string)", n.Right, len(n.Left.Val().U.(string)))
1054				} else if n.Right.Val().U.(*Mpint).Cmp(maxintval[TINT]) > 0 {
1055					yyerror("invalid %s index %v (index too large)", why, n.Right)
1056				}
1057			}
1058
1059		case TMAP:
1060			n.Etype = 0
1061			n.Right = defaultlit(n.Right, t.Key())
1062			if n.Right.Type != nil {
1063				n.Right = assignconv(n.Right, t.Key(), "map index")
1064			}
1065			n.Type = t.Val()
1066			n.Op = OINDEXMAP
1067		}
1068
1069		break OpSwitch
1070
1071	case ORECV:
1072		ok |= Etop | Erv
1073		n.Left = typecheck(n.Left, Erv)
1074		n.Left = defaultlit(n.Left, nil)
1075		l := n.Left
1076		t := l.Type
1077		if t == nil {
1078			n.Type = nil
1079			return n
1080		}
1081		if !t.IsChan() {
1082			yyerror("invalid operation: %v (receive from non-chan type %v)", n, t)
1083			n.Type = nil
1084			return n
1085		}
1086
1087		if !t.ChanDir().CanRecv() {
1088			yyerror("invalid operation: %v (receive from send-only type %v)", n, t)
1089			n.Type = nil
1090			return n
1091		}
1092
1093		n.Type = t.Elem()
1094		break OpSwitch
1095
1096	case OSEND:
1097		ok |= Etop
1098		n.Left = typecheck(n.Left, Erv)
1099		l := n.Left
1100		n.Right = typecheck(n.Right, Erv)
1101		n.Left = defaultlit(n.Left, nil)
1102		l = n.Left
1103		t := l.Type
1104		if t == nil {
1105			n.Type = nil
1106			return n
1107		}
1108		if !t.IsChan() {
1109			yyerror("invalid operation: %v (send to non-chan type %v)", n, t)
1110			n.Type = nil
1111			return n
1112		}
1113
1114		if !t.ChanDir().CanSend() {
1115			yyerror("invalid operation: %v (send to receive-only type %v)", n, t)
1116			n.Type = nil
1117			return n
1118		}
1119
1120		n.Right = defaultlit(n.Right, t.Elem())
1121		r := n.Right
1122		if r.Type == nil {
1123			n.Type = nil
1124			return n
1125		}
1126		n.Right = assignconv(r, l.Type.Elem(), "send")
1127
1128		// TODO: more aggressive
1129		n.Etype = 0
1130
1131		n.Type = nil
1132		break OpSwitch
1133
1134	case OSLICE, OSLICE3:
1135		ok |= Erv
1136		n.Left = typecheck(n.Left, Erv)
1137		low, high, max := n.SliceBounds()
1138		hasmax := n.Op.IsSlice3()
1139		low = typecheck(low, Erv)
1140		high = typecheck(high, Erv)
1141		max = typecheck(max, Erv)
1142		n.Left = defaultlit(n.Left, nil)
1143		low = indexlit(low)
1144		high = indexlit(high)
1145		max = indexlit(max)
1146		n.SetSliceBounds(low, high, max)
1147		l := n.Left
1148		if l.Type == nil {
1149			n.Type = nil
1150			return n
1151		}
1152		if l.Type.IsArray() {
1153			if !islvalue(n.Left) {
1154				yyerror("invalid operation %v (slice of unaddressable value)", n)
1155				n.Type = nil
1156				return n
1157			}
1158
1159			n.Left = nod(OADDR, n.Left, nil)
1160			n.Left.SetImplicit(true)
1161			n.Left = typecheck(n.Left, Erv)
1162			l = n.Left
1163		}
1164		t := l.Type
1165		var tp *types.Type
1166		if t.IsString() {
1167			if hasmax {
1168				yyerror("invalid operation %v (3-index slice of string)", n)
1169				n.Type = nil
1170				return n
1171			}
1172			n.Type = t
1173			n.Op = OSLICESTR
1174		} else if t.IsPtr() && t.Elem().IsArray() {
1175			tp = t.Elem()
1176			n.Type = types.NewSlice(tp.Elem())
1177			dowidth(n.Type)
1178			if hasmax {
1179				n.Op = OSLICE3ARR
1180			} else {
1181				n.Op = OSLICEARR
1182			}
1183		} else if t.IsSlice() {
1184			n.Type = t
1185		} else {
1186			yyerror("cannot slice %v (type %v)", l, t)
1187			n.Type = nil
1188			return n
1189		}
1190
1191		if low != nil && !checksliceindex(l, low, tp) {
1192			n.Type = nil
1193			return n
1194		}
1195		if high != nil && !checksliceindex(l, high, tp) {
1196			n.Type = nil
1197			return n
1198		}
1199		if max != nil && !checksliceindex(l, max, tp) {
1200			n.Type = nil
1201			return n
1202		}
1203		if !checksliceconst(low, high) || !checksliceconst(low, max) || !checksliceconst(high, max) {
1204			n.Type = nil
1205			return n
1206		}
1207		break OpSwitch
1208
1209	// call and call like
1210	case OCALL:
1211		n.Left = typecheck(n.Left, Erv|Etype|Ecall)
1212		if n.Left.Diag() {
1213			n.SetDiag(true)
1214		}
1215
1216		l := n.Left
1217
1218		if l.Op == ONAME && l.Etype != 0 {
1219			// TODO(marvin): Fix Node.EType type union.
1220			if n.Isddd() && Op(l.Etype) != OAPPEND {
1221				yyerror("invalid use of ... with builtin %v", l)
1222			}
1223
1224			// builtin: OLEN, OCAP, etc.
1225			// TODO(marvin): Fix Node.EType type union.
1226			n.Op = Op(l.Etype)
1227			n.Left = n.Right
1228			n.Right = nil
1229			n = typecheck1(n, top)
1230			return n
1231		}
1232
1233		n.Left = defaultlit(n.Left, nil)
1234		l = n.Left
1235		if l.Op == OTYPE {
1236			if n.Isddd() || l.Type.IsDDDArray() {
1237				if !l.Type.Broke() {
1238					yyerror("invalid use of ... in type conversion to %v", l.Type)
1239				}
1240				n.SetDiag(true)
1241			}
1242
1243			// pick off before type-checking arguments
1244			ok |= Erv
1245
1246			// turn CALL(type, arg) into CONV(arg) w/ type
1247			n.Left = nil
1248
1249			n.Op = OCONV
1250			n.Type = l.Type
1251			if !onearg(n, "conversion to %v", l.Type) {
1252				n.Type = nil
1253				return n
1254			}
1255			n = typecheck1(n, top)
1256			return n
1257		}
1258
1259		if n.List.Len() == 1 && !n.Isddd() {
1260			n.List.SetFirst(typecheck(n.List.First(), Erv|Efnstruct))
1261		} else {
1262			typecheckslice(n.List.Slice(), Erv)
1263		}
1264		t := l.Type
1265		if t == nil {
1266			n.Type = nil
1267			return n
1268		}
1269		checkwidth(t)
1270
1271		switch l.Op {
1272		case ODOTINTER:
1273			n.Op = OCALLINTER
1274
1275		case ODOTMETH:
1276			n.Op = OCALLMETH
1277
1278			// typecheckaste was used here but there wasn't enough
1279			// information further down the call chain to know if we
1280			// were testing a method receiver for unexported fields.
1281			// It isn't necessary, so just do a sanity check.
1282			tp := t.Recv().Type
1283
1284			if l.Left == nil || !eqtype(l.Left.Type, tp) {
1285				Fatalf("method receiver")
1286			}
1287
1288		default:
1289			n.Op = OCALLFUNC
1290			if t.Etype != TFUNC {
1291				yyerror("cannot call non-function %v (type %v)", l, t)
1292				n.Type = nil
1293				return n
1294			}
1295		}
1296
1297		typecheckaste(OCALL, n.Left, n.Isddd(), t.Params(), n.List, func() string { return fmt.Sprintf("argument to %v", n.Left) })
1298		ok |= Etop
1299		if t.Results().NumFields() == 0 {
1300			break OpSwitch
1301		}
1302		ok |= Erv
1303		if t.Results().NumFields() == 1 {
1304			n.Type = l.Type.Results().Field(0).Type
1305
1306			if n.Op == OCALLFUNC && n.Left.Op == ONAME && isRuntimePkg(n.Left.Sym.Pkg) && n.Left.Sym.Name == "getg" {
1307				// Emit code for runtime.getg() directly instead of calling function.
1308				// Most such rewrites (for example the similar one for math.Sqrt) should be done in walk,
1309				// so that the ordering pass can make sure to preserve the semantics of the original code
1310				// (in particular, the exact time of the function call) by introducing temporaries.
1311				// In this case, we know getg() always returns the same result within a given function
1312				// and we want to avoid the temporaries, so we do the rewrite earlier than is typical.
1313				n.Op = OGETG
1314			}
1315
1316			break OpSwitch
1317		}
1318
1319		// multiple return
1320		if top&(Efnstruct|Etop) == 0 {
1321			yyerror("multiple-value %v() in single-value context", l)
1322			break OpSwitch
1323		}
1324
1325		n.Type = l.Type.Results()
1326
1327		break OpSwitch
1328
1329	case OALIGNOF, OOFFSETOF, OSIZEOF:
1330		ok |= Erv
1331		if !onearg(n, "%v", n.Op) {
1332			n.Type = nil
1333			return n
1334		}
1335
1336		// any side effects disappear; ignore init
1337		var r Node
1338		nodconst(&r, types.Types[TUINTPTR], evalunsafe(n))
1339		r.Orig = n
1340		n = &r
1341
1342		break OpSwitch
1343
1344	case OCAP, OLEN:
1345		ok |= Erv
1346		if !onearg(n, "%v", n.Op) {
1347			n.Type = nil
1348			return n
1349		}
1350
1351		n.Left = typecheck(n.Left, Erv)
1352		n.Left = defaultlit(n.Left, nil)
1353		n.Left = implicitstar(n.Left)
1354		l := n.Left
1355		t := l.Type
1356		if t == nil {
1357			n.Type = nil
1358			return n
1359		}
1360
1361		var ok bool
1362		if n.Op == OLEN {
1363			ok = okforlen[t.Etype]
1364		} else {
1365			ok = okforcap[t.Etype]
1366		}
1367		if !ok {
1368			yyerror("invalid argument %L for %v", l, n.Op)
1369			n.Type = nil
1370			return n
1371		}
1372
1373		// result might be constant
1374		var res int64 = -1 // valid if >= 0
1375		switch t.Etype {
1376		case TSTRING:
1377			if Isconst(l, CTSTR) {
1378				res = int64(len(l.Val().U.(string)))
1379			}
1380
1381		case TARRAY:
1382			if !callrecv(l) {
1383				res = t.NumElem()
1384			}
1385		}
1386		if res >= 0 {
1387			var r Node
1388			nodconst(&r, types.Types[TINT], res)
1389			r.Orig = n
1390			n = &r
1391		}
1392
1393		n.Type = types.Types[TINT]
1394		break OpSwitch
1395
1396	case OREAL, OIMAG:
1397		ok |= Erv
1398		if !onearg(n, "%v", n.Op) {
1399			n.Type = nil
1400			return n
1401		}
1402
1403		n.Left = typecheck(n.Left, Erv)
1404		l := n.Left
1405		t := l.Type
1406		if t == nil {
1407			n.Type = nil
1408			return n
1409		}
1410
1411		if t.Etype != TIDEAL && !t.IsComplex() {
1412			yyerror("invalid argument %L for %v", l, n.Op)
1413			n.Type = nil
1414			return n
1415		}
1416
1417		// if the argument is a constant, the result is a constant
1418		// (any untyped numeric constant can be represented as a
1419		// complex number)
1420		if l.Op == OLITERAL {
1421			var re, im *Mpflt
1422			switch consttype(l) {
1423			case CTINT, CTRUNE:
1424				re = newMpflt()
1425				re.SetInt(l.Val().U.(*Mpint))
1426				// im = 0
1427			case CTFLT:
1428				re = l.Val().U.(*Mpflt)
1429				// im = 0
1430			case CTCPLX:
1431				re = &l.Val().U.(*Mpcplx).Real
1432				im = &l.Val().U.(*Mpcplx).Imag
1433			default:
1434				yyerror("invalid argument %L for %v", l, n.Op)
1435				n.Type = nil
1436				return n
1437			}
1438			if n.Op == OIMAG {
1439				if im == nil {
1440					im = newMpflt()
1441				}
1442				re = im
1443			}
1444			orig := n
1445			n = nodfltconst(re)
1446			n.Orig = orig
1447		}
1448
1449		// determine result type
1450		et := t.Etype
1451		switch et {
1452		case TIDEAL:
1453			// result is ideal
1454		case TCOMPLEX64:
1455			et = TFLOAT32
1456		case TCOMPLEX128:
1457			et = TFLOAT64
1458		default:
1459			Fatalf("unexpected Etype: %v\n", et)
1460		}
1461		n.Type = types.Types[et]
1462		break OpSwitch
1463
1464	case OCOMPLEX:
1465		ok |= Erv
1466		var r *Node
1467		var l *Node
1468		if n.List.Len() == 1 {
1469			typecheckslice(n.List.Slice(), Efnstruct)
1470			if n.List.First().Op != OCALLFUNC && n.List.First().Op != OCALLMETH {
1471				yyerror("invalid operation: complex expects two arguments")
1472				n.Type = nil
1473				return n
1474			}
1475
1476			t := n.List.First().Left.Type
1477			if !t.IsKind(TFUNC) {
1478				// Bail. This error will be reported elsewhere.
1479				return n
1480			}
1481			if t.Results().NumFields() != 2 {
1482				yyerror("invalid operation: complex expects two arguments, %v returns %d results", n.List.First(), t.Results().NumFields())
1483				n.Type = nil
1484				return n
1485			}
1486
1487			t = n.List.First().Type
1488			l = asNode(t.Field(0).Nname)
1489			r = asNode(t.Field(1).Nname)
1490		} else {
1491			if !twoarg(n) {
1492				n.Type = nil
1493				return n
1494			}
1495			n.Left = typecheck(n.Left, Erv)
1496			n.Right = typecheck(n.Right, Erv)
1497			l = n.Left
1498			r = n.Right
1499			if l.Type == nil || r.Type == nil {
1500				n.Type = nil
1501				return n
1502			}
1503			l, r = defaultlit2(l, r, false)
1504			if l.Type == nil || r.Type == nil {
1505				n.Type = nil
1506				return n
1507			}
1508			n.Left = l
1509			n.Right = r
1510		}
1511
1512		if !eqtype(l.Type, r.Type) {
1513			yyerror("invalid operation: %v (mismatched types %v and %v)", n, l.Type, r.Type)
1514			n.Type = nil
1515			return n
1516		}
1517
1518		var t *types.Type
1519		switch l.Type.Etype {
1520		default:
1521			yyerror("invalid operation: %v (arguments have type %v, expected floating-point)", n, l.Type)
1522			n.Type = nil
1523			return n
1524
1525		case TIDEAL:
1526			t = types.Types[TIDEAL]
1527
1528		case TFLOAT32:
1529			t = types.Types[TCOMPLEX64]
1530
1531		case TFLOAT64:
1532			t = types.Types[TCOMPLEX128]
1533		}
1534
1535		if l.Op == OLITERAL && r.Op == OLITERAL {
1536			// make it a complex literal
1537			r = nodcplxlit(l.Val(), r.Val())
1538
1539			r.Orig = n
1540			n = r
1541		}
1542
1543		n.Type = t
1544		break OpSwitch
1545
1546	case OCLOSE:
1547		if !onearg(n, "%v", n.Op) {
1548			n.Type = nil
1549			return n
1550		}
1551		n.Left = typecheck(n.Left, Erv)
1552		n.Left = defaultlit(n.Left, nil)
1553		l := n.Left
1554		t := l.Type
1555		if t == nil {
1556			n.Type = nil
1557			return n
1558		}
1559		if !t.IsChan() {
1560			yyerror("invalid operation: %v (non-chan type %v)", n, t)
1561			n.Type = nil
1562			return n
1563		}
1564
1565		if !t.ChanDir().CanSend() {
1566			yyerror("invalid operation: %v (cannot close receive-only channel)", n)
1567			n.Type = nil
1568			return n
1569		}
1570
1571		ok |= Etop
1572		break OpSwitch
1573
1574	case ODELETE:
1575		args := n.List
1576		if args.Len() == 0 {
1577			yyerror("missing arguments to delete")
1578			n.Type = nil
1579			return n
1580		}
1581
1582		if args.Len() == 1 {
1583			yyerror("missing second (key) argument to delete")
1584			n.Type = nil
1585			return n
1586		}
1587
1588		if args.Len() != 2 {
1589			yyerror("too many arguments to delete")
1590			n.Type = nil
1591			return n
1592		}
1593
1594		ok |= Etop
1595		typecheckslice(args.Slice(), Erv)
1596		l := args.First()
1597		r := args.Second()
1598		if l.Type != nil && !l.Type.IsMap() {
1599			yyerror("first argument to delete must be map; have %L", l.Type)
1600			n.Type = nil
1601			return n
1602		}
1603
1604		args.SetSecond(assignconv(r, l.Type.Key(), "delete"))
1605		break OpSwitch
1606
1607	case OAPPEND:
1608		ok |= Erv
1609		args := n.List
1610		if args.Len() == 0 {
1611			yyerror("missing arguments to append")
1612			n.Type = nil
1613			return n
1614		}
1615
1616		if args.Len() == 1 && !n.Isddd() {
1617			args.SetFirst(typecheck(args.First(), Erv|Efnstruct))
1618		} else {
1619			typecheckslice(args.Slice(), Erv)
1620		}
1621
1622		t := args.First().Type
1623		if t == nil {
1624			n.Type = nil
1625			return n
1626		}
1627
1628		// Unpack multiple-return result before type-checking.
1629		var funarg *types.Type
1630		if t.IsFuncArgStruct() {
1631			funarg = t
1632			t = t.Field(0).Type
1633		}
1634
1635		n.Type = t
1636		if !t.IsSlice() {
1637			if Isconst(args.First(), CTNIL) {
1638				yyerror("first argument to append must be typed slice; have untyped nil")
1639				n.Type = nil
1640				return n
1641			}
1642
1643			yyerror("first argument to append must be slice; have %L", t)
1644			n.Type = nil
1645			return n
1646		}
1647
1648		if n.Isddd() {
1649			if args.Len() == 1 {
1650				yyerror("cannot use ... on first argument to append")
1651				n.Type = nil
1652				return n
1653			}
1654
1655			if args.Len() != 2 {
1656				yyerror("too many arguments to append")
1657				n.Type = nil
1658				return n
1659			}
1660
1661			if t.Elem().IsKind(TUINT8) && args.Second().Type.IsString() {
1662				args.SetSecond(defaultlit(args.Second(), types.Types[TSTRING]))
1663				break OpSwitch
1664			}
1665
1666			args.SetSecond(assignconv(args.Second(), t.Orig, "append"))
1667			break OpSwitch
1668		}
1669
1670		if funarg != nil {
1671			for _, t := range funarg.FieldSlice()[1:] {
1672				if assignop(t.Type, n.Type.Elem(), nil) == 0 {
1673					yyerror("cannot append %v value to []%v", t.Type, n.Type.Elem())
1674				}
1675			}
1676		} else {
1677			as := args.Slice()[1:]
1678			for i, n := range as {
1679				if n.Type == nil {
1680					continue
1681				}
1682				as[i] = assignconv(n, t.Elem(), "append")
1683				checkwidth(as[i].Type) // ensure width is calculated for backend
1684			}
1685		}
1686
1687		break OpSwitch
1688
1689	case OCOPY:
1690		ok |= Etop | Erv
1691		args := n.List
1692		if args.Len() < 2 {
1693			yyerror("missing arguments to copy")
1694			n.Type = nil
1695			return n
1696		}
1697
1698		if args.Len() > 2 {
1699			yyerror("too many arguments to copy")
1700			n.Type = nil
1701			return n
1702		}
1703
1704		n.Left = args.First()
1705		n.Right = args.Second()
1706		n.List.Set(nil)
1707		n.Type = types.Types[TINT]
1708		n.Left = typecheck(n.Left, Erv)
1709		n.Right = typecheck(n.Right, Erv)
1710		if n.Left.Type == nil || n.Right.Type == nil {
1711			n.Type = nil
1712			return n
1713		}
1714		n.Left = defaultlit(n.Left, nil)
1715		n.Right = defaultlit(n.Right, nil)
1716		if n.Left.Type == nil || n.Right.Type == nil {
1717			n.Type = nil
1718			return n
1719		}
1720
1721		// copy([]byte, string)
1722		if n.Left.Type.IsSlice() && n.Right.Type.IsString() {
1723			if eqtype(n.Left.Type.Elem(), types.Bytetype) {
1724				break OpSwitch
1725			}
1726			yyerror("arguments to copy have different element types: %L and string", n.Left.Type)
1727			n.Type = nil
1728			return n
1729		}
1730
1731		if !n.Left.Type.IsSlice() || !n.Right.Type.IsSlice() {
1732			if !n.Left.Type.IsSlice() && !n.Right.Type.IsSlice() {
1733				yyerror("arguments to copy must be slices; have %L, %L", n.Left.Type, n.Right.Type)
1734			} else if !n.Left.Type.IsSlice() {
1735				yyerror("first argument to copy should be slice; have %L", n.Left.Type)
1736			} else {
1737				yyerror("second argument to copy should be slice or string; have %L", n.Right.Type)
1738			}
1739			n.Type = nil
1740			return n
1741		}
1742
1743		if !eqtype(n.Left.Type.Elem(), n.Right.Type.Elem()) {
1744			yyerror("arguments to copy have different element types: %L and %L", n.Left.Type, n.Right.Type)
1745			n.Type = nil
1746			return n
1747		}
1748
1749		break OpSwitch
1750
1751	case OCONV:
1752		ok |= Erv
1753		saveorignode(n)
1754		checkwidth(n.Type) // ensure width is calculated for backend
1755		n.Left = typecheck(n.Left, Erv)
1756		n.Left = convlit1(n.Left, n.Type, true, noReuse)
1757		t := n.Left.Type
1758		if t == nil || n.Type == nil {
1759			n.Type = nil
1760			return n
1761		}
1762		var why string
1763		n.Op = convertop(t, n.Type, &why)
1764		if n.Op == 0 {
1765			if !n.Diag() && !n.Type.Broke() {
1766				yyerror("cannot convert %L to type %v%s", n.Left, n.Type, why)
1767				n.SetDiag(true)
1768			}
1769
1770			n.Op = OCONV
1771		}
1772
1773		switch n.Op {
1774		case OCONVNOP:
1775			if n.Left.Op == OLITERAL {
1776				r := nod(OXXX, nil, nil)
1777				n.Op = OCONV
1778				n.Orig = r
1779				*r = *n
1780				n.Op = OLITERAL
1781				n.SetVal(n.Left.Val())
1782			} else if t.Etype == n.Type.Etype {
1783				switch t.Etype {
1784				case TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128:
1785					// Floating point casts imply rounding and
1786					// so the conversion must be kept.
1787					n.Op = OCONV
1788				}
1789			}
1790
1791		// do not use stringtoarraylit.
1792		// generated code and compiler memory footprint is better without it.
1793		case OSTRARRAYBYTE:
1794			break
1795
1796		case OSTRARRAYRUNE:
1797			if n.Left.Op == OLITERAL {
1798				n = stringtoarraylit(n)
1799			}
1800		}
1801
1802		break OpSwitch
1803
1804	case OMAKE:
1805		ok |= Erv
1806		args := n.List.Slice()
1807		if len(args) == 0 {
1808			yyerror("missing argument to make")
1809			n.Type = nil
1810			return n
1811		}
1812
1813		n.List.Set(nil)
1814		l := args[0]
1815		l = typecheck(l, Etype)
1816		t := l.Type
1817		if t == nil {
1818			n.Type = nil
1819			return n
1820		}
1821
1822		i := 1
1823		switch t.Etype {
1824		default:
1825			yyerror("cannot make type %v", t)
1826			n.Type = nil
1827			return n
1828
1829		case TSLICE:
1830			if i >= len(args) {
1831				yyerror("missing len argument to make(%v)", t)
1832				n.Type = nil
1833				return n
1834			}
1835
1836			l = args[i]
1837			i++
1838			l = typecheck(l, Erv)
1839			var r *Node
1840			if i < len(args) {
1841				r = args[i]
1842				i++
1843				r = typecheck(r, Erv)
1844			}
1845
1846			if l.Type == nil || (r != nil && r.Type == nil) {
1847				n.Type = nil
1848				return n
1849			}
1850			if !checkmake(t, "len", l) || r != nil && !checkmake(t, "cap", r) {
1851				n.Type = nil
1852				return n
1853			}
1854			if Isconst(l, CTINT) && r != nil && Isconst(r, CTINT) && l.Val().U.(*Mpint).Cmp(r.Val().U.(*Mpint)) > 0 {
1855				yyerror("len larger than cap in make(%v)", t)
1856				n.Type = nil
1857				return n
1858			}
1859
1860			n.Left = l
1861			n.Right = r
1862			n.Op = OMAKESLICE
1863
1864		case TMAP:
1865			if i < len(args) {
1866				l = args[i]
1867				i++
1868				l = typecheck(l, Erv)
1869				l = defaultlit(l, types.Types[TINT])
1870				if l.Type == nil {
1871					n.Type = nil
1872					return n
1873				}
1874				if !checkmake(t, "size", l) {
1875					n.Type = nil
1876					return n
1877				}
1878				n.Left = l
1879			} else {
1880				n.Left = nodintconst(0)
1881			}
1882			n.Op = OMAKEMAP
1883
1884		case TCHAN:
1885			l = nil
1886			if i < len(args) {
1887				l = args[i]
1888				i++
1889				l = typecheck(l, Erv)
1890				l = defaultlit(l, types.Types[TINT])
1891				if l.Type == nil {
1892					n.Type = nil
1893					return n
1894				}
1895				if !checkmake(t, "buffer", l) {
1896					n.Type = nil
1897					return n
1898				}
1899				n.Left = l
1900			} else {
1901				n.Left = nodintconst(0)
1902			}
1903			n.Op = OMAKECHAN
1904		}
1905
1906		if i < len(args) {
1907			yyerror("too many arguments to make(%v)", t)
1908			n.Op = OMAKE
1909			n.Type = nil
1910			return n
1911		}
1912
1913		n.Type = t
1914		break OpSwitch
1915
1916	case ONEW:
1917		ok |= Erv
1918		args := n.List
1919		if args.Len() == 0 {
1920			yyerror("missing argument to new")
1921			n.Type = nil
1922			return n
1923		}
1924
1925		l := args.First()
1926		l = typecheck(l, Etype)
1927		t := l.Type
1928		if t == nil {
1929			n.Type = nil
1930			return n
1931		}
1932		if args.Len() > 1 {
1933			yyerror("too many arguments to new(%v)", t)
1934			n.Type = nil
1935			return n
1936		}
1937
1938		n.Left = l
1939		n.Type = types.NewPtr(t)
1940		break OpSwitch
1941
1942	case OPRINT, OPRINTN:
1943		ok |= Etop
1944		typecheckslice(n.List.Slice(), Erv)
1945		ls := n.List.Slice()
1946		for i1, n1 := range ls {
1947			// Special case for print: int constant is int64, not int.
1948			if Isconst(n1, CTINT) {
1949				ls[i1] = defaultlit(ls[i1], types.Types[TINT64])
1950			} else {
1951				ls[i1] = defaultlit(ls[i1], nil)
1952			}
1953		}
1954
1955		break OpSwitch
1956
1957	case OPANIC:
1958		ok |= Etop
1959		if !onearg(n, "panic") {
1960			n.Type = nil
1961			return n
1962		}
1963		n.Left = typecheck(n.Left, Erv)
1964		n.Left = defaultlit(n.Left, types.Types[TINTER])
1965		if n.Left.Type == nil {
1966			n.Type = nil
1967			return n
1968		}
1969		break OpSwitch
1970
1971	case ORECOVER:
1972		ok |= Erv | Etop
1973		if n.List.Len() != 0 {
1974			yyerror("too many arguments to recover")
1975			n.Type = nil
1976			return n
1977		}
1978
1979		n.Type = types.Types[TINTER]
1980		break OpSwitch
1981
1982	case OCLOSURE:
1983		ok |= Erv
1984		typecheckclosure(n, top)
1985		if n.Type == nil {
1986			return n
1987		}
1988		break OpSwitch
1989
1990	case OITAB:
1991		ok |= Erv
1992		n.Left = typecheck(n.Left, Erv)
1993		t := n.Left.Type
1994		if t == nil {
1995			n.Type = nil
1996			return n
1997		}
1998		if !t.IsInterface() {
1999			Fatalf("OITAB of %v", t)
2000		}
2001		n.Type = types.NewPtr(types.Types[TUINTPTR])
2002		break OpSwitch
2003
2004	case OIDATA:
2005		// Whoever creates the OIDATA node must know a priori the concrete type at that moment,
2006		// usually by just having checked the OITAB.
2007		Fatalf("cannot typecheck interface data %v", n)
2008		break OpSwitch
2009
2010	case OSPTR:
2011		ok |= Erv
2012		n.Left = typecheck(n.Left, Erv)
2013		t := n.Left.Type
2014		if t == nil {
2015			n.Type = nil
2016			return n
2017		}
2018		if !t.IsSlice() && !t.IsString() {
2019			Fatalf("OSPTR of %v", t)
2020		}
2021		if t.IsString() {
2022			n.Type = types.NewPtr(types.Types[TUINT8])
2023		} else {
2024			n.Type = types.NewPtr(t.Elem())
2025		}
2026		break OpSwitch
2027
2028	case OCLOSUREVAR:
2029		ok |= Erv
2030		break OpSwitch
2031
2032	case OCFUNC:
2033		ok |= Erv
2034		n.Left = typecheck(n.Left, Erv)
2035		n.Type = types.Types[TUINTPTR]
2036		break OpSwitch
2037
2038	case OCONVNOP:
2039		ok |= Erv
2040		n.Left = typecheck(n.Left, Erv)
2041		break OpSwitch
2042
2043	// statements
2044	case OAS:
2045		ok |= Etop
2046
2047		typecheckas(n)
2048
2049		// Code that creates temps does not bother to set defn, so do it here.
2050		if n.Left.Op == ONAME && n.Left.IsAutoTmp() {
2051			n.Left.Name.Defn = n
2052		}
2053		break OpSwitch
2054
2055	case OAS2:
2056		ok |= Etop
2057		typecheckas2(n)
2058		break OpSwitch
2059
2060	case OBREAK,
2061		OCONTINUE,
2062		ODCL,
2063		OEMPTY,
2064		OGOTO,
2065		OXFALL,
2066		OVARKILL,
2067		OVARLIVE:
2068		ok |= Etop
2069		break OpSwitch
2070
2071	case OLABEL:
2072		ok |= Etop
2073		decldepth++
2074		if n.Left.Sym.IsBlank() {
2075			// Empty identifier is valid but useless.
2076			// Eliminate now to simplify life later.
2077			// See issues 7538, 11589, 11593.
2078			n.Op = OEMPTY
2079			n.Left = nil
2080		}
2081		break OpSwitch
2082
2083	case ODEFER:
2084		ok |= Etop
2085		n.Left = typecheck(n.Left, Etop|Erv)
2086		if !n.Left.Diag() {
2087			checkdefergo(n)
2088		}
2089		break OpSwitch
2090
2091	case OPROC:
2092		ok |= Etop
2093		n.Left = typecheck(n.Left, Etop|Erv)
2094		checkdefergo(n)
2095		break OpSwitch
2096
2097	case OFOR, OFORUNTIL:
2098		ok |= Etop
2099		typecheckslice(n.Ninit.Slice(), Etop)
2100		decldepth++
2101		n.Left = typecheck(n.Left, Erv)
2102		if n.Left != nil {
2103			t := n.Left.Type
2104			if t != nil && !t.IsBoolean() {
2105				yyerror("non-bool %L used as for condition", n.Left)
2106			}
2107		}
2108		n.Right = typecheck(n.Right, Etop)
2109		typecheckslice(n.Nbody.Slice(), Etop)
2110		decldepth--
2111		break OpSwitch
2112
2113	case OIF:
2114		ok |= Etop
2115		typecheckslice(n.Ninit.Slice(), Etop)
2116		n.Left = typecheck(n.Left, Erv)
2117		if n.Left != nil {
2118			t := n.Left.Type
2119			if t != nil && !t.IsBoolean() {
2120				yyerror("non-bool %L used as if condition", n.Left)
2121			}
2122		}
2123		typecheckslice(n.Nbody.Slice(), Etop)
2124		typecheckslice(n.Rlist.Slice(), Etop)
2125		break OpSwitch
2126
2127	case ORETURN:
2128		ok |= Etop
2129		if n.List.Len() == 1 {
2130			typecheckslice(n.List.Slice(), Erv|Efnstruct)
2131		} else {
2132			typecheckslice(n.List.Slice(), Erv)
2133		}
2134		if Curfn == nil {
2135			yyerror("return outside function")
2136			n.Type = nil
2137			return n
2138		}
2139
2140		if Curfn.Type.FuncType().Outnamed && n.List.Len() == 0 {
2141			break OpSwitch
2142		}
2143		typecheckaste(ORETURN, nil, false, Curfn.Type.Results(), n.List, func() string { return "return argument" })
2144		break OpSwitch
2145
2146	case ORETJMP:
2147		ok |= Etop
2148		break OpSwitch
2149
2150	case OSELECT:
2151		ok |= Etop
2152		typecheckselect(n)
2153		break OpSwitch
2154
2155	case OSWITCH:
2156		ok |= Etop
2157		typecheckswitch(n)
2158		break OpSwitch
2159
2160	case ORANGE:
2161		ok |= Etop
2162		typecheckrange(n)
2163		break OpSwitch
2164
2165	case OTYPESW:
2166		yyerror("use of .(type) outside type switch")
2167		n.Type = nil
2168		return n
2169
2170	case OXCASE:
2171		ok |= Etop
2172		typecheckslice(n.List.Slice(), Erv)
2173		typecheckslice(n.Nbody.Slice(), Etop)
2174		break OpSwitch
2175
2176	case ODCLFUNC:
2177		ok |= Etop
2178		typecheckfunc(n)
2179		break OpSwitch
2180
2181	case ODCLCONST:
2182		ok |= Etop
2183		n.Left = typecheck(n.Left, Erv)
2184		break OpSwitch
2185
2186	case ODCLTYPE:
2187		ok |= Etop
2188		n.Left = typecheck(n.Left, Etype)
2189		checkwidth(n.Left.Type)
2190		if n.Left.Type != nil && n.Left.Type.NotInHeap() && n.Left.Name.Param.Pragma&NotInHeap == 0 {
2191			// The type contains go:notinheap types, so it
2192			// must be marked as such (alternatively, we
2193			// could silently propagate go:notinheap).
2194			yyerror("type %v must be go:notinheap", n.Left.Type)
2195		}
2196		break OpSwitch
2197	}
2198
2199	t := n.Type
2200	if t != nil && !t.IsFuncArgStruct() && n.Op != OTYPE {
2201		switch t.Etype {
2202		case TFUNC, // might have TANY; wait until it's called
2203			TANY, TFORW, TIDEAL, TNIL, TBLANK:
2204			break
2205
2206		default:
2207			checkwidth(t)
2208		}
2209	}
2210
2211	if safemode && !inimport && compiling_wrappers == 0 && t != nil && t.Etype == TUNSAFEPTR {
2212		yyerror("cannot use unsafe.Pointer")
2213	}
2214
2215	evconst(n)
2216	if n.Op == OTYPE && top&Etype == 0 {
2217		if !n.Type.Broke() {
2218			yyerror("type %v is not an expression", n.Type)
2219		}
2220		n.Type = nil
2221		return n
2222	}
2223
2224	if top&(Erv|Etype) == Etype && n.Op != OTYPE {
2225		yyerror("%v is not a type", n)
2226		n.Type = nil
2227		return n
2228	}
2229
2230	// TODO(rsc): simplify
2231	if (top&(Ecall|Erv|Etype) != 0) && top&Etop == 0 && ok&(Erv|Etype|Ecall) == 0 {
2232		yyerror("%v used as value", n)
2233		n.Type = nil
2234		return n
2235	}
2236
2237	if (top&Etop != 0) && top&(Ecall|Erv|Etype) == 0 && ok&Etop == 0 {
2238		if !n.Diag() {
2239			yyerror("%v evaluated but not used", n)
2240			n.SetDiag(true)
2241		}
2242
2243		n.Type = nil
2244		return n
2245	}
2246
2247	return n
2248}
2249
2250func checksliceindex(l *Node, r *Node, tp *types.Type) bool {
2251	t := r.Type
2252	if t == nil {
2253		return false
2254	}
2255	if !t.IsInteger() {
2256		yyerror("invalid slice index %v (type %v)", r, t)
2257		return false
2258	}
2259
2260	if r.Op == OLITERAL {
2261		if r.Int64() < 0 {
2262			yyerror("invalid slice index %v (index must be non-negative)", r)
2263			return false
2264		} else if tp != nil && tp.NumElem() >= 0 && r.Int64() > tp.NumElem() {
2265			yyerror("invalid slice index %v (out of bounds for %d-element array)", r, tp.NumElem())
2266			return false
2267		} else if Isconst(l, CTSTR) && r.Int64() > int64(len(l.Val().U.(string))) {
2268			yyerror("invalid slice index %v (out of bounds for %d-byte string)", r, len(l.Val().U.(string)))
2269			return false
2270		} else if r.Val().U.(*Mpint).Cmp(maxintval[TINT]) > 0 {
2271			yyerror("invalid slice index %v (index too large)", r)
2272			return false
2273		}
2274	}
2275
2276	return true
2277}
2278
2279func checksliceconst(lo *Node, hi *Node) bool {
2280	if lo != nil && hi != nil && lo.Op == OLITERAL && hi.Op == OLITERAL && lo.Val().U.(*Mpint).Cmp(hi.Val().U.(*Mpint)) > 0 {
2281		yyerror("invalid slice index: %v > %v", lo, hi)
2282		return false
2283	}
2284
2285	return true
2286}
2287
2288func checkdefergo(n *Node) {
2289	what := "defer"
2290	if n.Op == OPROC {
2291		what = "go"
2292	}
2293
2294	switch n.Left.Op {
2295	// ok
2296	case OCALLINTER,
2297		OCALLMETH,
2298		OCALLFUNC,
2299		OCLOSE,
2300		OCOPY,
2301		ODELETE,
2302		OPANIC,
2303		OPRINT,
2304		OPRINTN,
2305		ORECOVER:
2306		return
2307
2308	case OAPPEND,
2309		OCAP,
2310		OCOMPLEX,
2311		OIMAG,
2312		OLEN,
2313		OMAKE,
2314		OMAKESLICE,
2315		OMAKECHAN,
2316		OMAKEMAP,
2317		ONEW,
2318		OREAL,
2319		OLITERAL: // conversion or unsafe.Alignof, Offsetof, Sizeof
2320		if n.Left.Orig != nil && n.Left.Orig.Op == OCONV {
2321			break
2322		}
2323		yyerror("%s discards result of %v", what, n.Left)
2324		return
2325	}
2326
2327	// type is broken or missing, most likely a method call on a broken type
2328	// we will warn about the broken type elsewhere. no need to emit a potentially confusing error
2329	if n.Left.Type == nil || n.Left.Type.Broke() {
2330		return
2331	}
2332
2333	if !n.Diag() {
2334		// The syntax made sure it was a call, so this must be
2335		// a conversion.
2336		n.SetDiag(true)
2337		yyerror("%s requires function call, not conversion", what)
2338	}
2339}
2340
2341// The result of implicitstar MUST be assigned back to n, e.g.
2342// 	n.Left = implicitstar(n.Left)
2343func implicitstar(n *Node) *Node {
2344	// insert implicit * if needed for fixed array
2345	t := n.Type
2346	if t == nil || !t.IsPtr() {
2347		return n
2348	}
2349	t = t.Elem()
2350	if t == nil {
2351		return n
2352	}
2353	if !t.IsArray() {
2354		return n
2355	}
2356	n = nod(OIND, n, nil)
2357	n.SetImplicit(true)
2358	n = typecheck(n, Erv)
2359	return n
2360}
2361
2362func onearg(n *Node, f string, args ...interface{}) bool {
2363	if n.Left != nil {
2364		return true
2365	}
2366	if n.List.Len() == 0 {
2367		p := fmt.Sprintf(f, args...)
2368		yyerror("missing argument to %s: %v", p, n)
2369		return false
2370	}
2371
2372	if n.List.Len() > 1 {
2373		p := fmt.Sprintf(f, args...)
2374		yyerror("too many arguments to %s: %v", p, n)
2375		n.Left = n.List.First()
2376		n.List.Set(nil)
2377		return false
2378	}
2379
2380	n.Left = n.List.First()
2381	n.List.Set(nil)
2382	return true
2383}
2384
2385func twoarg(n *Node) bool {
2386	if n.Left != nil {
2387		return true
2388	}
2389	if n.List.Len() == 0 {
2390		yyerror("missing argument to %v - %v", n.Op, n)
2391		return false
2392	}
2393
2394	n.Left = n.List.First()
2395	if n.List.Len() == 1 {
2396		yyerror("missing argument to %v - %v", n.Op, n)
2397		n.List.Set(nil)
2398		return false
2399	}
2400
2401	if n.List.Len() > 2 {
2402		yyerror("too many arguments to %v - %v", n.Op, n)
2403		n.List.Set(nil)
2404		return false
2405	}
2406
2407	n.Right = n.List.Second()
2408	n.List.Set(nil)
2409	return true
2410}
2411
2412func lookdot1(errnode *Node, s *types.Sym, t *types.Type, fs *types.Fields, dostrcmp int) *types.Field {
2413	var r *types.Field
2414	for _, f := range fs.Slice() {
2415		if dostrcmp != 0 && f.Sym.Name == s.Name {
2416			return f
2417		}
2418		if dostrcmp == 2 && strings.EqualFold(f.Sym.Name, s.Name) {
2419			return f
2420		}
2421		if f.Sym != s {
2422			continue
2423		}
2424		if r != nil {
2425			if errnode != nil {
2426				yyerror("ambiguous selector %v", errnode)
2427			} else if t.IsPtr() {
2428				yyerror("ambiguous selector (%v).%v", t, s)
2429			} else {
2430				yyerror("ambiguous selector %v.%v", t, s)
2431			}
2432			break
2433		}
2434
2435		r = f
2436	}
2437
2438	return r
2439}
2440
2441func looktypedot(n *Node, t *types.Type, dostrcmp int) bool {
2442	s := n.Sym
2443
2444	if t.IsInterface() {
2445		f1 := lookdot1(n, s, t, t.Fields(), dostrcmp)
2446		if f1 == nil {
2447			return false
2448		}
2449
2450		n.Sym = methodsym(n.Sym, t, false)
2451		n.Xoffset = f1.Offset
2452		n.Type = f1.Type
2453		n.Op = ODOTINTER
2454		return true
2455	}
2456
2457	// Find the base type: methtype will fail if t
2458	// is not of the form T or *T.
2459	mt := methtype(t)
2460	if mt == nil {
2461		return false
2462	}
2463
2464	expandmeth(mt)
2465	f2 := lookdot1(n, s, mt, mt.AllMethods(), dostrcmp)
2466	if f2 == nil {
2467		return false
2468	}
2469
2470	// disallow T.m if m requires *T receiver
2471	if f2.Type.Recv().Type.IsPtr() && !t.IsPtr() && f2.Embedded != 2 && !isifacemethod(f2.Type) {
2472		yyerror("invalid method expression %v (needs pointer receiver: (*%v).%S)", n, t, f2.Sym)
2473		return false
2474	}
2475
2476	n.Sym = methodsym(n.Sym, t, false)
2477	n.Xoffset = f2.Offset
2478	n.Type = f2.Type
2479	n.Op = ODOTMETH
2480	return true
2481}
2482
2483func derefall(t *types.Type) *types.Type {
2484	for t != nil && t.Etype == types.Tptr {
2485		t = t.Elem()
2486	}
2487	return t
2488}
2489
2490type typeSymKey struct {
2491	t *types.Type
2492	s *types.Sym
2493}
2494
2495// dotField maps (*types.Type, *types.Sym) pairs to the corresponding struct field (*types.Type with Etype==TFIELD).
2496// It is a cache for use during usefield in walk.go, only enabled when field tracking.
2497var dotField = map[typeSymKey]*types.Field{}
2498
2499func lookdot(n *Node, t *types.Type, dostrcmp int) *types.Field {
2500	s := n.Sym
2501
2502	dowidth(t)
2503	var f1 *types.Field
2504	if t.IsStruct() || t.IsInterface() {
2505		f1 = lookdot1(n, s, t, t.Fields(), dostrcmp)
2506	}
2507
2508	var f2 *types.Field
2509	if n.Left.Type == t || n.Left.Type.Sym == nil {
2510		mt := methtype(t)
2511		if mt != nil {
2512			f2 = lookdot1(n, s, mt, mt.Methods(), dostrcmp)
2513		}
2514	}
2515
2516	if f1 != nil {
2517		if dostrcmp > 1 {
2518			// Already in the process of diagnosing an error.
2519			return f1
2520		}
2521		if f2 != nil {
2522			yyerror("%v is both field and method", n.Sym)
2523		}
2524		if f1.Offset == BADWIDTH {
2525			Fatalf("lookdot badwidth %v %p", f1, f1)
2526		}
2527		n.Xoffset = f1.Offset
2528		n.Type = f1.Type
2529		if objabi.Fieldtrack_enabled > 0 {
2530			dotField[typeSymKey{t.Orig, s}] = f1
2531		}
2532		if t.IsInterface() {
2533			if n.Left.Type.IsPtr() {
2534				n.Left = nod(OIND, n.Left, nil) // implicitstar
2535				n.Left.SetImplicit(true)
2536				n.Left = typecheck(n.Left, Erv)
2537			}
2538
2539			n.Op = ODOTINTER
2540		}
2541
2542		return f1
2543	}
2544
2545	if f2 != nil {
2546		if dostrcmp > 1 {
2547			// Already in the process of diagnosing an error.
2548			return f2
2549		}
2550		tt := n.Left.Type
2551		dowidth(tt)
2552		rcvr := f2.Type.Recv().Type
2553		if !eqtype(rcvr, tt) {
2554			if rcvr.Etype == types.Tptr && eqtype(rcvr.Elem(), tt) {
2555				checklvalue(n.Left, "call pointer method on")
2556				n.Left = nod(OADDR, n.Left, nil)
2557				n.Left.SetImplicit(true)
2558				n.Left = typecheck(n.Left, Etype|Erv)
2559			} else if tt.Etype == types.Tptr && rcvr.Etype != types.Tptr && eqtype(tt.Elem(), rcvr) {
2560				n.Left = nod(OIND, n.Left, nil)
2561				n.Left.SetImplicit(true)
2562				n.Left = typecheck(n.Left, Etype|Erv)
2563			} else if tt.Etype == types.Tptr && tt.Elem().Etype == types.Tptr && eqtype(derefall(tt), derefall(rcvr)) {
2564				yyerror("calling method %v with receiver %L requires explicit dereference", n.Sym, n.Left)
2565				for tt.Etype == types.Tptr {
2566					// Stop one level early for method with pointer receiver.
2567					if rcvr.Etype == types.Tptr && tt.Elem().Etype != types.Tptr {
2568						break
2569					}
2570					n.Left = nod(OIND, n.Left, nil)
2571					n.Left.SetImplicit(true)
2572					n.Left = typecheck(n.Left, Etype|Erv)
2573					tt = tt.Elem()
2574				}
2575			} else {
2576				Fatalf("method mismatch: %v for %v", rcvr, tt)
2577			}
2578		}
2579
2580		pll := n
2581		ll := n.Left
2582		for ll.Left != nil && (ll.Op == ODOT || ll.Op == ODOTPTR || ll.Op == OIND) {
2583			pll = ll
2584			ll = ll.Left
2585		}
2586		if pll.Implicit() && ll.Type.IsPtr() && ll.Type.Sym != nil && asNode(ll.Type.Sym.Def) != nil && asNode(ll.Type.Sym.Def).Op == OTYPE {
2587			// It is invalid to automatically dereference a named pointer type when selecting a method.
2588			// Make n.Left == ll to clarify error message.
2589			n.Left = ll
2590			return nil
2591		}
2592
2593		n.Sym = methodsym(n.Sym, n.Left.Type, false)
2594		n.Xoffset = f2.Offset
2595		n.Type = f2.Type
2596
2597		n.Op = ODOTMETH
2598
2599		return f2
2600	}
2601
2602	return nil
2603}
2604
2605func nokeys(l Nodes) bool {
2606	for _, n := range l.Slice() {
2607		if n.Op == OKEY || n.Op == OSTRUCTKEY {
2608			return false
2609		}
2610	}
2611	return true
2612}
2613
2614func hasddd(t *types.Type) bool {
2615	for _, tl := range t.Fields().Slice() {
2616		if tl.Isddd() {
2617			return true
2618		}
2619	}
2620
2621	return false
2622}
2623
2624// typecheck assignment: type list = expression list
2625func typecheckaste(op Op, call *Node, isddd bool, tstruct *types.Type, nl Nodes, desc func() string) {
2626	var t *types.Type
2627	var n *Node
2628	var n1 int
2629	var n2 int
2630	var i int
2631
2632	lno := lineno
2633
2634	if tstruct.Broke() {
2635		goto out
2636	}
2637
2638	n = nil
2639	if nl.Len() == 1 {
2640		n = nl.First()
2641		if n.Type != nil {
2642			if n.Type.IsFuncArgStruct() {
2643				if !hasddd(tstruct) {
2644					n1 := tstruct.NumFields()
2645					n2 := n.Type.NumFields()
2646					if n2 > n1 {
2647						goto toomany
2648					}
2649					if n2 < n1 {
2650						goto notenough
2651					}
2652				}
2653
2654				lfs := tstruct.FieldSlice()
2655				rfs := n.Type.FieldSlice()
2656				var why string
2657				for i, tl := range lfs {
2658					if tl.Isddd() {
2659						for _, tn := range rfs[i:] {
2660							if assignop(tn.Type, tl.Type.Elem(), &why) == 0 {
2661								if call != nil {
2662									yyerror("cannot use %v as type %v in argument to %v%s", tn.Type, tl.Type.Elem(), call, why)
2663								} else {
2664									yyerror("cannot use %v as type %v in %s%s", tn.Type, tl.Type.Elem(), desc(), why)
2665								}
2666							}
2667						}
2668						goto out
2669					}
2670
2671					if i >= len(rfs) {
2672						goto notenough
2673					}
2674					tn := rfs[i]
2675					if assignop(tn.Type, tl.Type, &why) == 0 {
2676						if call != nil {
2677							yyerror("cannot use %v as type %v in argument to %v%s", tn.Type, tl.Type, call, why)
2678						} else {
2679							yyerror("cannot use %v as type %v in %s%s", tn.Type, tl.Type, desc(), why)
2680						}
2681					}
2682				}
2683
2684				if len(rfs) > len(lfs) {
2685					goto toomany
2686				}
2687				goto out
2688			}
2689		}
2690	}
2691
2692	n1 = tstruct.NumFields()
2693	n2 = nl.Len()
2694	if !hasddd(tstruct) {
2695		if n2 > n1 {
2696			goto toomany
2697		}
2698		if n2 < n1 {
2699			goto notenough
2700		}
2701	} else {
2702		if !isddd {
2703			if n2 < n1-1 {
2704				goto notenough
2705			}
2706		} else {
2707			if n2 > n1 {
2708				goto toomany
2709			}
2710			if n2 < n1 {
2711				goto notenough
2712			}
2713		}
2714	}
2715
2716	i = 0
2717	for _, tl := range tstruct.Fields().Slice() {
2718		t = tl.Type
2719		if tl.Isddd() {
2720			if isddd {
2721				if i >= nl.Len() {
2722					goto notenough
2723				}
2724				if nl.Len()-i > 1 {
2725					goto toomany
2726				}
2727				n = nl.Index(i)
2728				setlineno(n)
2729				if n.Type != nil {
2730					nl.SetIndex(i, assignconvfn(n, t, desc))
2731				}
2732				goto out
2733			}
2734
2735			for ; i < nl.Len(); i++ {
2736				n = nl.Index(i)
2737				setlineno(n)
2738				if n.Type != nil {
2739					nl.SetIndex(i, assignconvfn(n, t.Elem(), desc))
2740				}
2741			}
2742
2743			goto out
2744		}
2745
2746		if i >= nl.Len() {
2747			goto notenough
2748		}
2749		n = nl.Index(i)
2750		setlineno(n)
2751		if n.Type != nil {
2752			nl.SetIndex(i, assignconvfn(n, t, desc))
2753		}
2754		i++
2755	}
2756
2757	if i < nl.Len() {
2758		goto toomany
2759	}
2760	if isddd {
2761		if call != nil {
2762			yyerror("invalid use of ... in call to %v", call)
2763		} else {
2764			yyerror("invalid use of ... in %v", op)
2765		}
2766	}
2767
2768out:
2769	lineno = lno
2770	return
2771
2772notenough:
2773	if n == nil || !n.Diag() {
2774		details := errorDetails(nl, tstruct, isddd)
2775		if call != nil {
2776			// call is the expression being called, not the overall call.
2777			// Method expressions have the form T.M, and the compiler has
2778			// rewritten those to ONAME nodes but left T in Left.
2779			if call.Op == ONAME && call.Left != nil && call.Left.Op == OTYPE {
2780				yyerror("not enough arguments in call to method expression %v%s", call, details)
2781			} else {
2782				yyerror("not enough arguments in call to %v%s", call, details)
2783			}
2784		} else {
2785			yyerror("not enough arguments to %v%s", op, details)
2786		}
2787		if n != nil {
2788			n.SetDiag(true)
2789		}
2790	}
2791
2792	goto out
2793
2794toomany:
2795	details := errorDetails(nl, tstruct, isddd)
2796	if call != nil {
2797		yyerror("too many arguments in call to %v%s", call, details)
2798	} else {
2799		yyerror("too many arguments to %v%s", op, details)
2800	}
2801	goto out
2802}
2803
2804func errorDetails(nl Nodes, tstruct *types.Type, isddd bool) string {
2805	// If we don't know any type at a call site, let's suppress any return
2806	// message signatures. See Issue https://golang.org/issues/19012.
2807	if tstruct == nil {
2808		return ""
2809	}
2810	// If any node has an unknown type, suppress it as well
2811	for _, n := range nl.Slice() {
2812		if n.Type == nil {
2813			return ""
2814		}
2815	}
2816	return fmt.Sprintf("\n\thave %s\n\twant %v", nl.retsigerr(isddd), tstruct)
2817}
2818
2819// sigrepr is a type's representation to the outside world,
2820// in string representations of return signatures
2821// e.g in error messages about wrong arguments to return.
2822func sigrepr(t *types.Type) string {
2823	switch t {
2824	default:
2825		return t.String()
2826
2827	case types.Types[TIDEAL]:
2828		// "untyped number" is not commonly used
2829		// outside of the compiler, so let's use "number".
2830		return "number"
2831
2832	case types.Idealstring:
2833		return "string"
2834
2835	case types.Idealbool:
2836		return "bool"
2837	}
2838}
2839
2840// retsigerr returns the signature of the types
2841// at the respective return call site of a function.
2842func (nl Nodes) retsigerr(isddd bool) string {
2843	if nl.Len() < 1 {
2844		return "()"
2845	}
2846
2847	var typeStrings []string
2848	if nl.Len() == 1 && nl.First().Type != nil && nl.First().Type.IsFuncArgStruct() {
2849		for _, f := range nl.First().Type.Fields().Slice() {
2850			typeStrings = append(typeStrings, sigrepr(f.Type))
2851		}
2852	} else {
2853		for _, n := range nl.Slice() {
2854			typeStrings = append(typeStrings, sigrepr(n.Type))
2855		}
2856	}
2857
2858	ddd := ""
2859	if isddd {
2860		ddd = "..."
2861	}
2862	return fmt.Sprintf("(%s%s)", strings.Join(typeStrings, ", "), ddd)
2863}
2864
2865// type check composite
2866func fielddup(name string, hash map[string]bool) {
2867	if hash[name] {
2868		yyerror("duplicate field name in struct literal: %s", name)
2869		return
2870	}
2871	hash[name] = true
2872}
2873
2874func keydup(n *Node, hash map[uint32][]*Node) {
2875	orign := n
2876	if n.Op == OCONVIFACE {
2877		n = n.Left
2878	}
2879	evconst(n)
2880	if n.Op != OLITERAL {
2881		return // we don't check variables
2882	}
2883
2884	const PRIME1 = 3
2885
2886	var h uint32
2887	switch v := n.Val().U.(type) {
2888	default: // unknown, bool, nil
2889		h = 23
2890
2891	case *Mpint:
2892		h = uint32(v.Int64())
2893
2894	case *Mpflt:
2895		x := math.Float64bits(v.Float64())
2896		for i := 0; i < 8; i++ {
2897			h = h*PRIME1 + uint32(x&0xFF)
2898			x >>= 8
2899		}
2900
2901	case string:
2902		for i := 0; i < len(v); i++ {
2903			h = h*PRIME1 + uint32(v[i])
2904		}
2905	}
2906
2907	var cmp Node
2908	for _, a := range hash[h] {
2909		cmp.Op = OEQ
2910		cmp.Left = n
2911		if a.Op == OCONVIFACE && orign.Op == OCONVIFACE {
2912			a = a.Left
2913		}
2914		if !eqtype(a.Type, n.Type) {
2915			continue
2916		}
2917		cmp.Right = a
2918		evconst(&cmp)
2919		if cmp.Op != OLITERAL {
2920			// Sometimes evconst fails. See issue 12536.
2921			continue
2922		}
2923		if cmp.Val().U.(bool) {
2924			yyerror("duplicate key %v in map literal", n)
2925			return
2926		}
2927	}
2928
2929	hash[h] = append(hash[h], orign)
2930}
2931
2932// iscomptype reports whether type t is a composite literal type
2933// or a pointer to one.
2934func iscomptype(t *types.Type) bool {
2935	if t.IsPtr() {
2936		t = t.Elem()
2937	}
2938
2939	switch t.Etype {
2940	case TARRAY, TSLICE, TSTRUCT, TMAP:
2941		return true
2942	default:
2943		return false
2944	}
2945}
2946
2947func pushtype(n *Node, t *types.Type) {
2948	if n == nil || n.Op != OCOMPLIT || !iscomptype(t) {
2949		return
2950	}
2951
2952	if n.Right == nil {
2953		n.Right = typenod(t)
2954		n.SetImplicit(true)       // don't print
2955		n.Right.SetImplicit(true) // * is okay
2956	} else if Debug['s'] != 0 {
2957		n.Right = typecheck(n.Right, Etype)
2958		if n.Right.Type != nil && eqtype(n.Right.Type, t) {
2959			fmt.Printf("%v: redundant type: %v\n", n.Line(), t)
2960		}
2961	}
2962}
2963
2964// The result of typecheckcomplit MUST be assigned back to n, e.g.
2965// 	n.Left = typecheckcomplit(n.Left)
2966func typecheckcomplit(n *Node) *Node {
2967	lno := lineno
2968	defer func() {
2969		lineno = lno
2970	}()
2971
2972	if n.Right == nil {
2973		yyerrorl(n.Pos, "missing type in composite literal")
2974		n.Type = nil
2975		return n
2976	}
2977
2978	// Save original node (including n.Right)
2979	norig := nod(n.Op, nil, nil)
2980
2981	*norig = *n
2982
2983	setlineno(n.Right)
2984	n.Right = typecheck(n.Right, Etype|Ecomplit)
2985	l := n.Right // sic
2986	t := l.Type
2987	if t == nil {
2988		n.Type = nil
2989		return n
2990	}
2991	nerr := nerrors
2992	n.Type = t
2993
2994	if t.IsPtr() {
2995		// For better or worse, we don't allow pointers as the composite literal type,
2996		// except when using the &T syntax, which sets implicit on the OIND.
2997		if !n.Right.Implicit() {
2998			yyerror("invalid pointer type %v for composite literal (use &%v instead)", t, t.Elem())
2999			n.Type = nil
3000			return n
3001		}
3002
3003		// Also, the underlying type must be a struct, map, slice, or array.
3004		if !iscomptype(t) {
3005			yyerror("invalid pointer type %v for composite literal", t)
3006			n.Type = nil
3007			return n
3008		}
3009
3010		t = t.Elem()
3011	}
3012
3013	switch t.Etype {
3014	default:
3015		yyerror("invalid type for composite literal: %v", t)
3016		n.Type = nil
3017
3018	case TARRAY, TSLICE:
3019		// If there are key/value pairs, create a map to keep seen
3020		// keys so we can check for duplicate indices.
3021		var indices map[int64]bool
3022		for _, n1 := range n.List.Slice() {
3023			if n1.Op == OKEY {
3024				indices = make(map[int64]bool)
3025				break
3026			}
3027		}
3028
3029		var length, i int64
3030		checkBounds := t.IsArray() && !t.IsDDDArray()
3031		nl := n.List.Slice()
3032		for i2, l := range nl {
3033			setlineno(l)
3034			vp := &nl[i2]
3035			if l.Op == OKEY {
3036				l.Left = typecheck(l.Left, Erv)
3037				evconst(l.Left)
3038				i = nonnegintconst(l.Left)
3039				if i < 0 && !l.Left.Diag() {
3040					yyerror("index must be non-negative integer constant")
3041					l.Left.SetDiag(true)
3042					i = -(1 << 30) // stay negative for a while
3043				}
3044				vp = &l.Right
3045			}
3046
3047			if i >= 0 && indices != nil {
3048				if indices[i] {
3049					yyerror("duplicate index in array literal: %d", i)
3050				} else {
3051					indices[i] = true
3052				}
3053			}
3054
3055			r := *vp
3056			pushtype(r, t.Elem())
3057			r = typecheck(r, Erv)
3058			r = defaultlit(r, t.Elem())
3059			*vp = assignconv(r, t.Elem(), "array or slice literal")
3060
3061			i++
3062			if i > length {
3063				length = i
3064				if checkBounds && length > t.NumElem() {
3065					setlineno(l)
3066					yyerror("array index %d out of bounds [0:%d]", length-1, t.NumElem())
3067					checkBounds = false
3068				}
3069			}
3070		}
3071
3072		if t.IsDDDArray() {
3073			t.SetNumElem(length)
3074		}
3075		if t.IsSlice() {
3076			n.Right = nodintconst(length)
3077			n.Op = OSLICELIT
3078		} else {
3079			n.Op = OARRAYLIT
3080		}
3081
3082	case TMAP:
3083		hash := make(map[uint32][]*Node)
3084		for i3, l := range n.List.Slice() {
3085			setlineno(l)
3086			if l.Op != OKEY {
3087				n.List.SetIndex(i3, typecheck(n.List.Index(i3), Erv))
3088				yyerror("missing key in map literal")
3089				continue
3090			}
3091
3092			r := l.Left
3093			pushtype(r, t.Key())
3094			r = typecheck(r, Erv)
3095			r = defaultlit(r, t.Key())
3096			l.Left = assignconv(r, t.Key(), "map key")
3097			if l.Left.Op != OCONV {
3098				keydup(l.Left, hash)
3099			}
3100
3101			r = l.Right
3102			pushtype(r, t.Val())
3103			r = typecheck(r, Erv)
3104			r = defaultlit(r, t.Val())
3105			l.Right = assignconv(r, t.Val(), "map value")
3106		}
3107
3108		n.Op = OMAPLIT
3109
3110	case TSTRUCT:
3111		// Need valid field offsets for Xoffset below.
3112		dowidth(t)
3113
3114		bad := 0
3115		if n.List.Len() != 0 && nokeys(n.List) {
3116			// simple list of variables
3117			ls := n.List.Slice()
3118			for i, n1 := range ls {
3119				setlineno(n1)
3120				n1 = typecheck(n1, Erv)
3121				ls[i] = n1
3122				if i >= t.NumFields() {
3123					if bad == 0 {
3124						yyerror("too many values in struct initializer")
3125					}
3126					bad++
3127					continue
3128				}
3129
3130				f := t.Field(i)
3131				s := f.Sym
3132				if s != nil && !exportname(s.Name) && s.Pkg != localpkg {
3133					yyerror("implicit assignment of unexported field '%s' in %v literal", s.Name, t)
3134				}
3135				// No pushtype allowed here. Must name fields for that.
3136				n1 = assignconv(n1, f.Type, "field value")
3137				n1 = nodSym(OSTRUCTKEY, n1, f.Sym)
3138				n1.Xoffset = f.Offset
3139				ls[i] = n1
3140			}
3141			if len(ls) < t.NumFields() {
3142				yyerror("too few values in struct initializer")
3143			}
3144		} else {
3145			hash := make(map[string]bool)
3146
3147			// keyed list
3148			ls := n.List.Slice()
3149			for i, l := range ls {
3150				setlineno(l)
3151
3152				if l.Op == OKEY {
3153					key := l.Left
3154
3155					l.Op = OSTRUCTKEY
3156					l.Left = l.Right
3157					l.Right = nil
3158
3159					// An OXDOT uses the Sym field to hold
3160					// the field to the right of the dot,
3161					// so s will be non-nil, but an OXDOT
3162					// is never a valid struct literal key.
3163					if key.Sym == nil || key.Op == OXDOT || key.Sym.IsBlank() {
3164						yyerror("invalid field name %v in struct initializer", key)
3165						l.Left = typecheck(l.Left, Erv)
3166						continue
3167					}
3168
3169					// Sym might have resolved to name in other top-level
3170					// package, because of import dot. Redirect to correct sym
3171					// before we do the lookup.
3172					s := key.Sym
3173					if s.Pkg != localpkg && exportname(s.Name) {
3174						s1 := lookup(s.Name)
3175						if s1.Origpkg == s.Pkg {
3176							s = s1
3177						}
3178					}
3179					l.Sym = s
3180				}
3181
3182				if l.Op != OSTRUCTKEY {
3183					if bad == 0 {
3184						yyerror("mixture of field:value and value initializers")
3185					}
3186					bad++
3187					ls[i] = typecheck(ls[i], Erv)
3188					continue
3189				}
3190
3191				f := lookdot1(nil, l.Sym, t, t.Fields(), 0)
3192				if f == nil {
3193					yyerror("unknown field '%v' in struct literal of type %v", l.Sym, t)
3194					continue
3195				}
3196				fielddup(f.Sym.Name, hash)
3197				l.Xoffset = f.Offset
3198
3199				// No pushtype allowed here. Tried and rejected.
3200				l.Left = typecheck(l.Left, Erv)
3201				l.Left = assignconv(l.Left, f.Type, "field value")
3202			}
3203		}
3204
3205		n.Op = OSTRUCTLIT
3206	}
3207
3208	if nerr != nerrors {
3209		return n
3210	}
3211
3212	n.Orig = norig
3213	if n.Type.IsPtr() {
3214		n = nod(OPTRLIT, n, nil)
3215		n.SetTypecheck(1)
3216		n.Type = n.Left.Type
3217		n.Left.Type = t
3218		n.Left.SetTypecheck(1)
3219	}
3220
3221	n.Orig = norig
3222	return n
3223}
3224
3225// lvalue etc
3226func islvalue(n *Node) bool {
3227	switch n.Op {
3228	case OINDEX:
3229		if n.Left.Type != nil && n.Left.Type.IsArray() {
3230			return islvalue(n.Left)
3231		}
3232		if n.Left.Type != nil && n.Left.Type.IsString() {
3233			return false
3234		}
3235		fallthrough
3236	case OIND, ODOTPTR, OCLOSUREVAR:
3237		return true
3238
3239	case ODOT:
3240		return islvalue(n.Left)
3241
3242	case ONAME:
3243		if n.Class() == PFUNC {
3244			return false
3245		}
3246		return true
3247	}
3248
3249	return false
3250}
3251
3252func checklvalue(n *Node, verb string) {
3253	if !islvalue(n) {
3254		yyerror("cannot %s %v", verb, n)
3255	}
3256}
3257
3258func checkassign(stmt *Node, n *Node) {
3259	// Variables declared in ORANGE are assigned on every iteration.
3260	if n.Name == nil || n.Name.Defn != stmt || stmt.Op == ORANGE {
3261		r := outervalue(n)
3262		var l *Node
3263		for l = n; l != r; l = l.Left {
3264			l.SetAssigned(true)
3265			if l.IsClosureVar() {
3266				l.Name.Defn.SetAssigned(true)
3267			}
3268		}
3269
3270		l.SetAssigned(true)
3271		if l.IsClosureVar() {
3272			l.Name.Defn.SetAssigned(true)
3273		}
3274	}
3275
3276	if islvalue(n) {
3277		return
3278	}
3279	if n.Op == OINDEXMAP {
3280		n.Etype = 1
3281		return
3282	}
3283
3284	// have already complained about n being invalid
3285	if n.Type == nil {
3286		return
3287	}
3288
3289	if n.Op == ODOT && n.Left.Op == OINDEXMAP {
3290		yyerror("cannot assign to struct field %v in map", n)
3291	} else {
3292		yyerror("cannot assign to %v", n)
3293	}
3294	n.Type = nil
3295}
3296
3297func checkassignlist(stmt *Node, l Nodes) {
3298	for _, n := range l.Slice() {
3299		checkassign(stmt, n)
3300	}
3301}
3302
3303// Check whether l and r are the same side effect-free expression,
3304// so that it is safe to reuse one instead of computing both.
3305func samesafeexpr(l *Node, r *Node) bool {
3306	if l.Op != r.Op || !eqtype(l.Type, r.Type) {
3307		return false
3308	}
3309
3310	switch l.Op {
3311	case ONAME, OCLOSUREVAR:
3312		return l == r
3313
3314	case ODOT, ODOTPTR:
3315		return l.Sym != nil && r.Sym != nil && l.Sym == r.Sym && samesafeexpr(l.Left, r.Left)
3316
3317	case OIND, OCONVNOP:
3318		return samesafeexpr(l.Left, r.Left)
3319
3320	case OCONV:
3321		// Some conversions can't be reused, such as []byte(str).
3322		// Allow only numeric-ish types. This is a bit conservative.
3323		return issimple[l.Type.Etype] && samesafeexpr(l.Left, r.Left)
3324
3325	case OINDEX:
3326		return samesafeexpr(l.Left, r.Left) && samesafeexpr(l.Right, r.Right)
3327
3328	case OLITERAL:
3329		return eqval(l.Val(), r.Val())
3330	}
3331
3332	return false
3333}
3334
3335// type check assignment.
3336// if this assignment is the definition of a var on the left side,
3337// fill in the var's type.
3338func typecheckas(n *Node) {
3339	// delicate little dance.
3340	// the definition of n may refer to this assignment
3341	// as its definition, in which case it will call typecheckas.
3342	// in that case, do not call typecheck back, or it will cycle.
3343	// if the variable has a type (ntype) then typechecking
3344	// will not look at defn, so it is okay (and desirable,
3345	// so that the conversion below happens).
3346	n.Left = resolve(n.Left)
3347
3348	if n.Left.Name == nil || n.Left.Name.Defn != n || n.Left.Name.Param.Ntype != nil {
3349		n.Left = typecheck(n.Left, Erv|Easgn)
3350	}
3351
3352	n.Right = typecheck(n.Right, Erv)
3353	checkassign(n, n.Left)
3354	if n.Right != nil && n.Right.Type != nil {
3355		if n.Left.Type != nil {
3356			n.Right = assignconv(n.Right, n.Left.Type, "assignment")
3357		}
3358	}
3359
3360	if n.Left.Name != nil && n.Left.Name.Defn == n && n.Left.Name.Param.Ntype == nil {
3361		n.Right = defaultlit(n.Right, nil)
3362		n.Left.Type = n.Right.Type
3363	}
3364
3365	// second half of dance.
3366	// now that right is done, typecheck the left
3367	// just to get it over with.  see dance above.
3368	n.SetTypecheck(1)
3369
3370	if n.Left.Typecheck() == 0 {
3371		n.Left = typecheck(n.Left, Erv|Easgn)
3372	}
3373	if !isblank(n.Left) {
3374		checkwidth(n.Left.Type) // ensure width is calculated for backend
3375	}
3376}
3377
3378func checkassignto(src *types.Type, dst *Node) {
3379	var why string
3380
3381	if assignop(src, dst.Type, &why) == 0 {
3382		yyerror("cannot assign %v to %L in multiple assignment%s", src, dst, why)
3383		return
3384	}
3385}
3386
3387func typecheckas2(n *Node) {
3388	ls := n.List.Slice()
3389	for i1, n1 := range ls {
3390		// delicate little dance.
3391		n1 = resolve(n1)
3392		ls[i1] = n1
3393
3394		if n1.Name == nil || n1.Name.Defn != n || n1.Name.Param.Ntype != nil {
3395			ls[i1] = typecheck(ls[i1], Erv|Easgn)
3396		}
3397	}
3398
3399	cl := n.List.Len()
3400	cr := n.Rlist.Len()
3401	if cl > 1 && cr == 1 {
3402		n.Rlist.SetFirst(typecheck(n.Rlist.First(), Erv|Efnstruct))
3403	} else {
3404		typecheckslice(n.Rlist.Slice(), Erv)
3405	}
3406	checkassignlist(n, n.List)
3407
3408	var l *Node
3409	var r *Node
3410	if cl == cr {
3411		// easy
3412		ls := n.List.Slice()
3413		rs := n.Rlist.Slice()
3414		for il, nl := range ls {
3415			nr := rs[il]
3416			if nl.Type != nil && nr.Type != nil {
3417				rs[il] = assignconv(nr, nl.Type, "assignment")
3418			}
3419			if nl.Name != nil && nl.Name.Defn == n && nl.Name.Param.Ntype == nil {
3420				rs[il] = defaultlit(rs[il], nil)
3421				nl.Type = rs[il].Type
3422			}
3423		}
3424
3425		goto out
3426	}
3427
3428	l = n.List.First()
3429	r = n.Rlist.First()
3430
3431	// x,y,z = f()
3432	if cr == 1 {
3433		if r.Type == nil {
3434			goto out
3435		}
3436		switch r.Op {
3437		case OCALLMETH, OCALLINTER, OCALLFUNC:
3438			if !r.Type.IsFuncArgStruct() {
3439				break
3440			}
3441			cr = r.Type.NumFields()
3442			if cr != cl {
3443				goto mismatch
3444			}
3445			n.Op = OAS2FUNC
3446			for i, l := range n.List.Slice() {
3447				f := r.Type.Field(i)
3448				if f.Type != nil && l.Type != nil {
3449					checkassignto(f.Type, l)
3450				}
3451				if l.Name != nil && l.Name.Defn == n && l.Name.Param.Ntype == nil {
3452					l.Type = f.Type
3453				}
3454			}
3455			goto out
3456		}
3457	}
3458
3459	// x, ok = y
3460	if cl == 2 && cr == 1 {
3461		if r.Type == nil {
3462			goto out
3463		}
3464		switch r.Op {
3465		case OINDEXMAP, ORECV, ODOTTYPE:
3466			switch r.Op {
3467			case OINDEXMAP:
3468				n.Op = OAS2MAPR
3469
3470			case ORECV:
3471				n.Op = OAS2RECV
3472
3473			case ODOTTYPE:
3474				n.Op = OAS2DOTTYPE
3475				r.Op = ODOTTYPE2
3476			}
3477
3478			if l.Type != nil {
3479				checkassignto(r.Type, l)
3480			}
3481			if l.Name != nil && l.Name.Defn == n {
3482				l.Type = r.Type
3483			}
3484			l := n.List.Second()
3485			if l.Type != nil && !l.Type.IsBoolean() {
3486				checkassignto(types.Types[TBOOL], l)
3487			}
3488			if l.Name != nil && l.Name.Defn == n && l.Name.Param.Ntype == nil {
3489				l.Type = types.Types[TBOOL]
3490			}
3491			goto out
3492		}
3493	}
3494
3495mismatch:
3496	yyerror("cannot assign %d values to %d variables", cr, cl)
3497
3498	// second half of dance
3499out:
3500	n.SetTypecheck(1)
3501	ls = n.List.Slice()
3502	for i1, n1 := range ls {
3503		if n1.Typecheck() == 0 {
3504			ls[i1] = typecheck(ls[i1], Erv|Easgn)
3505		}
3506	}
3507}
3508
3509// type check function definition
3510func typecheckfunc(n *Node) {
3511	for _, ln := range n.Func.Dcl {
3512		if ln.Op == ONAME && (ln.Class() == PPARAM || ln.Class() == PPARAMOUT) {
3513			ln.Name.Decldepth = 1
3514		}
3515	}
3516
3517	n.Func.Nname = typecheck(n.Func.Nname, Erv|Easgn)
3518	t := n.Func.Nname.Type
3519	if t == nil {
3520		return
3521	}
3522	n.Type = t
3523	t.FuncType().Nname = asTypesNode(n.Func.Nname)
3524	rcvr := t.Recv()
3525	if rcvr != nil && n.Func.Shortname != nil {
3526		n.Func.Nname.Sym = methodname(n.Func.Shortname, rcvr.Type)
3527		declare(n.Func.Nname, PFUNC)
3528
3529		addmethod(n.Func.Shortname, t, true, n.Func.Pragma&Nointerface != 0)
3530	}
3531
3532	if Ctxt.Flag_dynlink && !inimport && n.Func.Nname != nil {
3533		makefuncsym(n.Func.Nname.Sym)
3534	}
3535}
3536
3537// The result of stringtoarraylit MUST be assigned back to n, e.g.
3538// 	n.Left = stringtoarraylit(n.Left)
3539func stringtoarraylit(n *Node) *Node {
3540	if n.Left.Op != OLITERAL || n.Left.Val().Ctype() != CTSTR {
3541		Fatalf("stringtoarraylit %v", n)
3542	}
3543
3544	s := n.Left.Val().U.(string)
3545	var l []*Node
3546	if n.Type.Elem().Etype == TUINT8 {
3547		// []byte
3548		for i := 0; i < len(s); i++ {
3549			l = append(l, nod(OKEY, nodintconst(int64(i)), nodintconst(int64(s[0]))))
3550		}
3551	} else {
3552		// []rune
3553		i := 0
3554		for _, r := range s {
3555			l = append(l, nod(OKEY, nodintconst(int64(i)), nodintconst(int64(r))))
3556			i++
3557		}
3558	}
3559
3560	nn := nod(OCOMPLIT, nil, typenod(n.Type))
3561	nn.List.Set(l)
3562	nn = typecheck(nn, Erv)
3563	return nn
3564}
3565
3566var ntypecheckdeftype int
3567
3568type mapqueueval struct {
3569	n   *Node
3570	lno src.XPos
3571}
3572
3573// tracks the line numbers at which forward types are first used as map keys
3574var mapqueue []mapqueueval
3575
3576func copytype(n *Node, t *types.Type) {
3577	if t.Etype == TFORW {
3578		// This type isn't computed yet; when it is, update n.
3579		t.ForwardType().Copyto = append(t.ForwardType().Copyto, asTypesNode(n))
3580		return
3581	}
3582
3583	embedlineno := n.Type.ForwardType().Embedlineno
3584	l := n.Type.ForwardType().Copyto
3585
3586	ptrBase := n.Type.PtrBase
3587	sliceOf := n.Type.SliceOf
3588
3589	// TODO(mdempsky): Fix Type rekinding.
3590	*n.Type = *t
3591
3592	t = n.Type
3593	t.Sym = n.Sym
3594	t.SetLocal(n.Local())
3595	if n.Name != nil {
3596		t.Vargen = n.Name.Vargen
3597	}
3598
3599	// spec: "The declared type does not inherit any methods bound
3600	// to the existing type, but the method set of an interface
3601	// type [...] remains unchanged."
3602	if !t.IsInterface() {
3603		*t.Methods() = types.Fields{}
3604		*t.AllMethods() = types.Fields{}
3605	}
3606
3607	t.Nod = asTypesNode(n)
3608	t.SetDeferwidth(false)
3609	t.PtrBase = ptrBase
3610	t.SliceOf = sliceOf
3611
3612	// Propagate go:notinheap pragma from the Name to the Type.
3613	if n.Name != nil && n.Name.Param != nil && n.Name.Param.Pragma&NotInHeap != 0 {
3614		t.SetNotInHeap(true)
3615	}
3616
3617	// Update nodes waiting on this type.
3618	for _, n := range l {
3619		copytype(asNode(n), t)
3620	}
3621
3622	// Double-check use of type as embedded type.
3623	lno := lineno
3624
3625	if embedlineno.IsKnown() {
3626		lineno = embedlineno
3627		if t.IsPtr() || t.IsUnsafePtr() {
3628			yyerror("embedded type cannot be a pointer")
3629		}
3630	}
3631
3632	lineno = lno
3633}
3634
3635func typecheckdeftype(n *Node) {
3636	ntypecheckdeftype++
3637	lno := lineno
3638	setlineno(n)
3639	n.Type.Sym = n.Sym
3640	n.SetTypecheck(1)
3641	n.Name.Param.Ntype = typecheck(n.Name.Param.Ntype, Etype)
3642	t := n.Name.Param.Ntype.Type
3643	if t == nil {
3644		n.SetDiag(true)
3645		n.Type = nil
3646		goto ret
3647	}
3648
3649	if n.Type == nil {
3650		n.SetDiag(true)
3651		goto ret
3652	}
3653
3654	// copy new type and clear fields
3655	// that don't come along.
3656	copytype(n, t)
3657
3658ret:
3659	lineno = lno
3660
3661	// if there are no type definitions going on, it's safe to
3662	// try to validate the map key types for the interfaces
3663	// we just read.
3664	if ntypecheckdeftype == 1 {
3665		for _, e := range mapqueue {
3666			lineno = e.lno
3667			if !IsComparable(e.n.Type) {
3668				yyerror("invalid map key type %v", e.n.Type)
3669			}
3670		}
3671		mapqueue = nil
3672		lineno = lno
3673	}
3674
3675	ntypecheckdeftype--
3676}
3677
3678func typecheckdef(n *Node) *Node {
3679	lno := lineno
3680	setlineno(n)
3681
3682	if n.Op == ONONAME {
3683		if !n.Diag() {
3684			n.SetDiag(true)
3685			if n.Pos.IsKnown() {
3686				lineno = n.Pos
3687			}
3688
3689			// Note: adderrorname looks for this string and
3690			// adds context about the outer expression
3691			yyerror("undefined: %v", n.Sym)
3692		}
3693
3694		return n
3695	}
3696
3697	if n.Walkdef() == 1 {
3698		return n
3699	}
3700
3701	typecheckdefstack = append(typecheckdefstack, n)
3702	if n.Walkdef() == 2 {
3703		flusherrors()
3704		fmt.Printf("typecheckdef loop:")
3705		for i := len(typecheckdefstack) - 1; i >= 0; i-- {
3706			n := typecheckdefstack[i]
3707			fmt.Printf(" %v", n.Sym)
3708		}
3709		fmt.Printf("\n")
3710		Fatalf("typecheckdef loop")
3711	}
3712
3713	n.SetWalkdef(2)
3714
3715	if n.Type != nil || n.Sym == nil { // builtin or no name
3716		goto ret
3717	}
3718
3719	switch n.Op {
3720	default:
3721		Fatalf("typecheckdef %v", n.Op)
3722
3723	case OGOTO, OLABEL, OPACK:
3724		// nothing to do here
3725
3726	case OLITERAL:
3727		if n.Name.Param.Ntype != nil {
3728			n.Name.Param.Ntype = typecheck(n.Name.Param.Ntype, Etype)
3729			n.Type = n.Name.Param.Ntype.Type
3730			n.Name.Param.Ntype = nil
3731			if n.Type == nil {
3732				n.SetDiag(true)
3733				goto ret
3734			}
3735		}
3736
3737		e := n.Name.Defn
3738		n.Name.Defn = nil
3739		if e == nil {
3740			lineno = n.Pos
3741			Dump("typecheckdef nil defn", n)
3742			yyerror("xxx")
3743		}
3744
3745		e = typecheck(e, Erv)
3746		if Isconst(e, CTNIL) {
3747			yyerror("const initializer cannot be nil")
3748			goto ret
3749		}
3750
3751		if e.Type != nil && e.Op != OLITERAL || !isgoconst(e) {
3752			if !e.Diag() {
3753				yyerror("const initializer %v is not a constant", e)
3754				e.SetDiag(true)
3755			}
3756
3757			goto ret
3758		}
3759
3760		t := n.Type
3761		if t != nil {
3762			if !okforconst[t.Etype] {
3763				yyerror("invalid constant type %v", t)
3764				goto ret
3765			}
3766
3767			if !e.Type.IsUntyped() && !eqtype(t, e.Type) {
3768				yyerror("cannot use %L as type %v in const initializer", e, t)
3769				goto ret
3770			}
3771
3772			e = convlit(e, t)
3773		}
3774
3775		n.SetVal(e.Val())
3776		n.Type = e.Type
3777
3778	case ONAME:
3779		if n.Name.Param.Ntype != nil {
3780			n.Name.Param.Ntype = typecheck(n.Name.Param.Ntype, Etype)
3781			n.Type = n.Name.Param.Ntype.Type
3782			if n.Type == nil {
3783				n.SetDiag(true)
3784				goto ret
3785			}
3786		}
3787
3788		if n.Type != nil {
3789			break
3790		}
3791		if n.Name.Defn == nil {
3792			if n.Etype != 0 { // like OPRINTN
3793				break
3794			}
3795			if nsavederrors+nerrors > 0 {
3796				// Can have undefined variables in x := foo
3797				// that make x have an n.name.Defn == nil.
3798				// If there are other errors anyway, don't
3799				// bother adding to the noise.
3800				break
3801			}
3802
3803			Fatalf("var without type, init: %v", n.Sym)
3804		}
3805
3806		if n.Name.Defn.Op == ONAME {
3807			n.Name.Defn = typecheck(n.Name.Defn, Erv)
3808			n.Type = n.Name.Defn.Type
3809			break
3810		}
3811
3812		n.Name.Defn = typecheck(n.Name.Defn, Etop) // fills in n.Type
3813
3814	case OTYPE:
3815		if p := n.Name.Param; p.Alias {
3816			// Type alias declaration: Simply use the rhs type - no need
3817			// to create a new type.
3818			// If we have a syntax error, p.Ntype may be nil.
3819			if p.Ntype != nil {
3820				p.Ntype = typecheck(p.Ntype, Etype)
3821				n.Type = p.Ntype.Type
3822				if n.Type == nil {
3823					n.SetDiag(true)
3824					goto ret
3825				}
3826				n.Sym.Def = asTypesNode(p.Ntype)
3827			}
3828			break
3829		}
3830
3831		// regular type declaration
3832		if Curfn != nil {
3833			defercheckwidth()
3834		}
3835		n.SetWalkdef(1)
3836		n.Type = types.New(TFORW)
3837		n.Type.Nod = asTypesNode(n)
3838		n.Type.Sym = n.Sym // TODO(gri) this also happens in typecheckdeftype(n) - where should it happen?
3839		nerrors0 := nerrors
3840		typecheckdeftype(n)
3841		if n.Type.Etype == TFORW && nerrors > nerrors0 {
3842			// Something went wrong during type-checking,
3843			// but it was reported. Silence future errors.
3844			n.Type.SetBroke(true)
3845		}
3846		if Curfn != nil {
3847			resumecheckwidth()
3848		}
3849	}
3850
3851ret:
3852	if n.Op != OLITERAL && n.Type != nil && n.Type.IsUntyped() {
3853		Fatalf("got %v for %v", n.Type, n)
3854	}
3855	last := len(typecheckdefstack) - 1
3856	if typecheckdefstack[last] != n {
3857		Fatalf("typecheckdefstack mismatch")
3858	}
3859	typecheckdefstack[last] = nil
3860	typecheckdefstack = typecheckdefstack[:last]
3861
3862	lineno = lno
3863	n.SetWalkdef(1)
3864	return n
3865}
3866
3867func checkmake(t *types.Type, arg string, n *Node) bool {
3868	if !n.Type.IsInteger() && n.Type.Etype != TIDEAL {
3869		yyerror("non-integer %s argument in make(%v) - %v", arg, t, n.Type)
3870		return false
3871	}
3872
3873	// Do range checks for constants before defaultlit
3874	// to avoid redundant "constant NNN overflows int" errors.
3875	switch consttype(n) {
3876	case CTINT, CTRUNE, CTFLT, CTCPLX:
3877		n.SetVal(toint(n.Val()))
3878		if n.Val().U.(*Mpint).CmpInt64(0) < 0 {
3879			yyerror("negative %s argument in make(%v)", arg, t)
3880			return false
3881		}
3882		if n.Val().U.(*Mpint).Cmp(maxintval[TINT]) > 0 {
3883			yyerror("%s argument too large in make(%v)", arg, t)
3884			return false
3885		}
3886	}
3887
3888	// defaultlit is necessary for non-constants too: n might be 1.1<<k.
3889	n = defaultlit(n, types.Types[TINT])
3890
3891	return true
3892}
3893
3894func markbreak(n *Node, implicit *Node) {
3895	if n == nil {
3896		return
3897	}
3898
3899	switch n.Op {
3900	case OBREAK:
3901		if n.Left == nil {
3902			if implicit != nil {
3903				implicit.SetHasBreak(true)
3904			}
3905		} else {
3906			lab := asNode(n.Left.Sym.Label)
3907			if lab != nil {
3908				lab.SetHasBreak(true)
3909			}
3910		}
3911	case OFOR, OFORUNTIL, OSWITCH, OTYPESW, OSELECT, ORANGE:
3912		implicit = n
3913		fallthrough
3914	default:
3915		markbreak(n.Left, implicit)
3916		markbreak(n.Right, implicit)
3917		markbreaklist(n.Ninit, implicit)
3918		markbreaklist(n.Nbody, implicit)
3919		markbreaklist(n.List, implicit)
3920		markbreaklist(n.Rlist, implicit)
3921	}
3922}
3923
3924func markbreaklist(l Nodes, implicit *Node) {
3925	s := l.Slice()
3926	for i := 0; i < len(s); i++ {
3927		n := s[i]
3928		if n == nil {
3929			continue
3930		}
3931		if n.Op == OLABEL && i+1 < len(s) && n.Name.Defn == s[i+1] {
3932			switch n.Name.Defn.Op {
3933			case OFOR, OFORUNTIL, OSWITCH, OTYPESW, OSELECT, ORANGE:
3934				n.Left.Sym.Label = asTypesNode(n.Name.Defn)
3935				markbreak(n.Name.Defn, n.Name.Defn)
3936				n.Left.Sym.Label = nil
3937				i++
3938				continue
3939			}
3940		}
3941
3942		markbreak(n, implicit)
3943	}
3944}
3945
3946// isterminating reports whether the Nodes list ends with a terminating statement.
3947func (l Nodes) isterminating() bool {
3948	s := l.Slice()
3949	c := len(s)
3950	if c == 0 {
3951		return false
3952	}
3953	return s[c-1].isterminating()
3954}
3955
3956// Isterminating reports whether the node n, the last one in a
3957// statement list, is a terminating statement.
3958func (n *Node) isterminating() bool {
3959	switch n.Op {
3960	// NOTE: OLABEL is treated as a separate statement,
3961	// not a separate prefix, so skipping to the last statement
3962	// in the block handles the labeled statement case by
3963	// skipping over the label. No case OLABEL here.
3964
3965	case OBLOCK:
3966		return n.List.isterminating()
3967
3968	case OGOTO, ORETURN, ORETJMP, OPANIC, OXFALL:
3969		return true
3970
3971	case OFOR, OFORUNTIL:
3972		if n.Left != nil {
3973			return false
3974		}
3975		if n.HasBreak() {
3976			return false
3977		}
3978		return true
3979
3980	case OIF:
3981		return n.Nbody.isterminating() && n.Rlist.isterminating()
3982
3983	case OSWITCH, OTYPESW, OSELECT:
3984		if n.HasBreak() {
3985			return false
3986		}
3987		def := 0
3988		for _, n1 := range n.List.Slice() {
3989			if !n1.Nbody.isterminating() {
3990				return false
3991			}
3992			if n1.List.Len() == 0 { // default
3993				def = 1
3994			}
3995		}
3996
3997		if n.Op != OSELECT && def == 0 {
3998			return false
3999		}
4000		return true
4001	}
4002
4003	return false
4004}
4005
4006// checkreturn makes sure that fn terminates appropriately.
4007func checkreturn(fn *Node) {
4008	if fn.Type.Results().NumFields() != 0 && fn.Nbody.Len() != 0 {
4009		markbreaklist(fn.Nbody, nil)
4010		if !fn.Nbody.isterminating() {
4011			yyerrorl(fn.Func.Endlineno, "missing return at end of function")
4012		}
4013	}
4014}
4015
4016func deadcode(fn *Node) {
4017	deadcodeslice(fn.Nbody)
4018}
4019
4020func deadcodeslice(nn Nodes) {
4021	for _, n := range nn.Slice() {
4022		if n == nil {
4023			continue
4024		}
4025		if n.Op == OIF && Isconst(n.Left, CTBOOL) {
4026			if n.Left.Bool() {
4027				n.Rlist = Nodes{}
4028			} else {
4029				n.Nbody = Nodes{}
4030			}
4031		}
4032		deadcodeslice(n.Ninit)
4033		deadcodeslice(n.Nbody)
4034		deadcodeslice(n.List)
4035		deadcodeslice(n.Rlist)
4036	}
4037}
4038