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