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