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