1
2
3
4
5 package typecheck
6
7 import (
8 "fmt"
9 "go/constant"
10 "strings"
11
12 "cmd/compile/internal/base"
13 "cmd/compile/internal/ir"
14 "cmd/compile/internal/types"
15 "cmd/internal/src"
16 )
17
18 func AssignExpr(n ir.Node) ir.Node { return typecheck(n, ctxExpr|ctxAssign) }
19 func Expr(n ir.Node) ir.Node { return typecheck(n, ctxExpr) }
20 func Stmt(n ir.Node) ir.Node { return typecheck(n, ctxStmt) }
21
22 func Exprs(exprs []ir.Node) { typecheckslice(exprs, ctxExpr) }
23 func Stmts(stmts []ir.Node) { typecheckslice(stmts, ctxStmt) }
24
25 func Call(pos src.XPos, callee ir.Node, args []ir.Node, dots bool) ir.Node {
26 call := ir.NewCallExpr(pos, ir.OCALL, callee, args)
27 call.IsDDD = dots
28 return typecheck(call, ctxStmt|ctxExpr)
29 }
30
31 func Callee(n ir.Node) ir.Node {
32 return typecheck(n, ctxExpr|ctxCallee)
33 }
34
35 var traceIndent []byte
36
37 func tracePrint(title string, n ir.Node) func(np *ir.Node) {
38 indent := traceIndent
39
40
41 var pos, op string
42 var tc uint8
43 if n != nil {
44 pos = base.FmtPos(n.Pos())
45 op = n.Op().String()
46 tc = n.Typecheck()
47 }
48
49 types.SkipSizeForTracing = true
50 defer func() { types.SkipSizeForTracing = false }()
51 fmt.Printf("%s: %s%s %p %s %v tc=%d\n", pos, indent, title, n, op, n, tc)
52 traceIndent = append(traceIndent, ". "...)
53
54 return func(np *ir.Node) {
55 traceIndent = traceIndent[:len(traceIndent)-2]
56
57
58 if np != nil {
59 n = *np
60 }
61
62
63
64 var tc uint8
65 var typ *types.Type
66 if n != nil {
67 pos = base.FmtPos(n.Pos())
68 op = n.Op().String()
69 tc = n.Typecheck()
70 typ = n.Type()
71 }
72
73 types.SkipSizeForTracing = true
74 defer func() { types.SkipSizeForTracing = false }()
75 fmt.Printf("%s: %s=> %p %s %v tc=%d type=%L\n", pos, indent, n, op, n, tc, typ)
76 }
77 }
78
79 const (
80 ctxStmt = 1 << iota
81 ctxExpr
82 ctxType
83 ctxCallee
84 ctxMultiOK
85 ctxAssign
86 )
87
88
89
90
91
92
93
94 func typecheckslice(l []ir.Node, top int) {
95 for i := range l {
96 l[i] = typecheck(l[i], top)
97 }
98 }
99
100 var _typekind = []string{
101 types.TINT: "int",
102 types.TUINT: "uint",
103 types.TINT8: "int8",
104 types.TUINT8: "uint8",
105 types.TINT16: "int16",
106 types.TUINT16: "uint16",
107 types.TINT32: "int32",
108 types.TUINT32: "uint32",
109 types.TINT64: "int64",
110 types.TUINT64: "uint64",
111 types.TUINTPTR: "uintptr",
112 types.TCOMPLEX64: "complex64",
113 types.TCOMPLEX128: "complex128",
114 types.TFLOAT32: "float32",
115 types.TFLOAT64: "float64",
116 types.TBOOL: "bool",
117 types.TSTRING: "string",
118 types.TPTR: "pointer",
119 types.TUNSAFEPTR: "unsafe.Pointer",
120 types.TSTRUCT: "struct",
121 types.TINTER: "interface",
122 types.TCHAN: "chan",
123 types.TMAP: "map",
124 types.TARRAY: "array",
125 types.TSLICE: "slice",
126 types.TFUNC: "func",
127 types.TNIL: "nil",
128 types.TIDEAL: "untyped number",
129 }
130
131 func typekind(t *types.Type) string {
132 if t.IsUntyped() {
133 return fmt.Sprintf("%v", t)
134 }
135 et := t.Kind()
136 if int(et) < len(_typekind) {
137 s := _typekind[et]
138 if s != "" {
139 return s
140 }
141 }
142 return fmt.Sprintf("etype=%d", et)
143 }
144
145
146
147
148
149 func typecheck(n ir.Node, top int) (res ir.Node) {
150 if n == nil {
151 return nil
152 }
153
154
155 if base.EnableTrace && base.Flag.LowerT {
156 defer tracePrint("typecheck", n)(&res)
157 }
158
159 lno := ir.SetPos(n)
160 defer func() { base.Pos = lno }()
161
162
163
164 if n.Typecheck() == 1 || n.Typecheck() == 3 {
165 switch n.Op() {
166 case ir.ONAME:
167 break
168
169 default:
170 return n
171 }
172 }
173
174 if n.Typecheck() == 2 {
175 base.FatalfAt(n.Pos(), "typechecking loop")
176 }
177
178 n.SetTypecheck(2)
179 n = typecheck1(n, top)
180 n.SetTypecheck(1)
181
182 t := n.Type()
183 if t != nil && !t.IsFuncArgStruct() && n.Op() != ir.OTYPE {
184 switch t.Kind() {
185 case types.TFUNC,
186 types.TANY, types.TFORW, types.TIDEAL, types.TNIL, types.TBLANK:
187 break
188
189 default:
190 types.CheckSize(t)
191 }
192 }
193
194 return n
195 }
196
197
198
199
200
201
202
203
204 func indexlit(n ir.Node) ir.Node {
205 if n != nil && n.Type() != nil && n.Type().Kind() == types.TIDEAL {
206 return DefaultLit(n, types.Types[types.TINT])
207 }
208 return n
209 }
210
211
212 func typecheck1(n ir.Node, top int) ir.Node {
213
214 for n.Op() == ir.OPAREN {
215 n = n.(*ir.ParenExpr).X
216 }
217
218 switch n.Op() {
219 default:
220 ir.Dump("typecheck", n)
221 base.Fatalf("typecheck %v", n.Op())
222 panic("unreachable")
223
224 case ir.ONAME:
225 n := n.(*ir.Name)
226 if n.BuiltinOp != 0 {
227 if top&ctxCallee == 0 {
228 base.Errorf("use of builtin %v not in function call", n.Sym())
229 n.SetType(nil)
230 return n
231 }
232 return n
233 }
234 if top&ctxAssign == 0 {
235
236 if ir.IsBlank(n) {
237 base.Errorf("cannot use _ as value")
238 n.SetType(nil)
239 return n
240 }
241 n.SetUsed(true)
242 }
243 return n
244
245
246 case ir.ODEREF:
247 n := n.(*ir.StarExpr)
248 return tcStar(n, top)
249
250
251 case ir.OASOP:
252 n := n.(*ir.AssignOpStmt)
253 n.X, n.Y = Expr(n.X), Expr(n.Y)
254 checkassign(n.X)
255 if n.IncDec && !okforarith[n.X.Type().Kind()] {
256 base.Errorf("invalid operation: %v (non-numeric type %v)", n, n.X.Type())
257 return n
258 }
259 switch n.AsOp {
260 case ir.OLSH, ir.ORSH:
261 n.X, n.Y, _ = tcShift(n, n.X, n.Y)
262 case ir.OADD, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OMOD, ir.OMUL, ir.OOR, ir.OSUB, ir.OXOR:
263 n.X, n.Y, _ = tcArith(n, n.AsOp, n.X, n.Y)
264 default:
265 base.Fatalf("invalid assign op: %v", n.AsOp)
266 }
267 return n
268
269
270 case ir.OANDAND, ir.OOROR:
271 n := n.(*ir.LogicalExpr)
272 n.X, n.Y = Expr(n.X), Expr(n.Y)
273 if n.X.Type() == nil || n.Y.Type() == nil {
274 n.SetType(nil)
275 return n
276 }
277
278
279
280 if !n.X.Type().IsBoolean() {
281 base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, n.Op(), typekind(n.X.Type()))
282 n.SetType(nil)
283 return n
284 }
285 if !n.Y.Type().IsBoolean() {
286 base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, n.Op(), typekind(n.Y.Type()))
287 n.SetType(nil)
288 return n
289 }
290 l, r, t := tcArith(n, n.Op(), n.X, n.Y)
291 n.X, n.Y = l, r
292 n.SetType(t)
293 return n
294
295
296 case ir.OLSH, ir.ORSH:
297 n := n.(*ir.BinaryExpr)
298 n.X, n.Y = Expr(n.X), Expr(n.Y)
299 l, r, t := tcShift(n, n.X, n.Y)
300 n.X, n.Y = l, r
301 n.SetType(t)
302 return n
303
304
305 case ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT, ir.ONE:
306 n := n.(*ir.BinaryExpr)
307 n.X, n.Y = Expr(n.X), Expr(n.Y)
308 l, r, t := tcArith(n, n.Op(), n.X, n.Y)
309 if t != nil {
310 n.X, n.Y = l, r
311 n.SetType(types.UntypedBool)
312 n.X, n.Y = defaultlit2(l, r, true)
313 }
314 return n
315
316
317 case ir.OADD, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OMOD, ir.OMUL, ir.OOR, ir.OSUB, ir.OXOR:
318 n := n.(*ir.BinaryExpr)
319 n.X, n.Y = Expr(n.X), Expr(n.Y)
320 l, r, t := tcArith(n, n.Op(), n.X, n.Y)
321 if t != nil && t.Kind() == types.TSTRING && n.Op() == ir.OADD {
322
323 var add *ir.AddStringExpr
324 if l.Op() == ir.OADDSTR {
325 add = l.(*ir.AddStringExpr)
326 add.SetPos(n.Pos())
327 } else {
328 add = ir.NewAddStringExpr(n.Pos(), []ir.Node{l})
329 }
330 if r.Op() == ir.OADDSTR {
331 r := r.(*ir.AddStringExpr)
332 add.List.Append(r.List.Take()...)
333 } else {
334 add.List.Append(r)
335 }
336 add.SetType(t)
337 return add
338 }
339 n.X, n.Y = l, r
340 n.SetType(t)
341 return n
342
343 case ir.OBITNOT, ir.ONEG, ir.ONOT, ir.OPLUS:
344 n := n.(*ir.UnaryExpr)
345 return tcUnaryArith(n)
346
347
348 case ir.OCOMPLIT:
349 return tcCompLit(n.(*ir.CompLitExpr))
350
351 case ir.OXDOT, ir.ODOT:
352 n := n.(*ir.SelectorExpr)
353 return tcDot(n, top)
354
355 case ir.ODOTTYPE:
356 n := n.(*ir.TypeAssertExpr)
357 return tcDotType(n)
358
359 case ir.OINDEX:
360 n := n.(*ir.IndexExpr)
361 return tcIndex(n)
362
363 case ir.ORECV:
364 n := n.(*ir.UnaryExpr)
365 return tcRecv(n)
366
367 case ir.OSEND:
368 n := n.(*ir.SendStmt)
369 return tcSend(n)
370
371 case ir.OSLICEHEADER:
372 n := n.(*ir.SliceHeaderExpr)
373 return tcSliceHeader(n)
374
375 case ir.OSTRINGHEADER:
376 n := n.(*ir.StringHeaderExpr)
377 return tcStringHeader(n)
378
379 case ir.OMAKESLICECOPY:
380 n := n.(*ir.MakeExpr)
381 return tcMakeSliceCopy(n)
382
383 case ir.OSLICE, ir.OSLICE3:
384 n := n.(*ir.SliceExpr)
385 return tcSlice(n)
386
387
388 case ir.OCALL:
389 n := n.(*ir.CallExpr)
390 return tcCall(n, top)
391
392 case ir.OCAP, ir.OLEN:
393 n := n.(*ir.UnaryExpr)
394 return tcLenCap(n)
395
396 case ir.OMIN, ir.OMAX:
397 n := n.(*ir.CallExpr)
398 return tcMinMax(n)
399
400 case ir.OREAL, ir.OIMAG:
401 n := n.(*ir.UnaryExpr)
402 return tcRealImag(n)
403
404 case ir.OCOMPLEX:
405 n := n.(*ir.BinaryExpr)
406 return tcComplex(n)
407
408 case ir.OCLEAR:
409 n := n.(*ir.UnaryExpr)
410 return tcClear(n)
411
412 case ir.OCLOSE:
413 n := n.(*ir.UnaryExpr)
414 return tcClose(n)
415
416 case ir.ODELETE:
417 n := n.(*ir.CallExpr)
418 return tcDelete(n)
419
420 case ir.OAPPEND:
421 n := n.(*ir.CallExpr)
422 return tcAppend(n)
423
424 case ir.OCOPY:
425 n := n.(*ir.BinaryExpr)
426 return tcCopy(n)
427
428 case ir.OCONV:
429 n := n.(*ir.ConvExpr)
430 return tcConv(n)
431
432 case ir.OMAKE:
433 n := n.(*ir.CallExpr)
434 return tcMake(n)
435
436 case ir.ONEW:
437 n := n.(*ir.UnaryExpr)
438 return tcNew(n)
439
440 case ir.OPRINT, ir.OPRINTLN:
441 n := n.(*ir.CallExpr)
442 return tcPrint(n)
443
444 case ir.OPANIC:
445 n := n.(*ir.UnaryExpr)
446 return tcPanic(n)
447
448 case ir.ORECOVER:
449 n := n.(*ir.CallExpr)
450 return tcRecover(n)
451
452 case ir.OUNSAFEADD:
453 n := n.(*ir.BinaryExpr)
454 return tcUnsafeAdd(n)
455
456 case ir.OUNSAFESLICE:
457 n := n.(*ir.BinaryExpr)
458 return tcUnsafeSlice(n)
459
460 case ir.OUNSAFESLICEDATA:
461 n := n.(*ir.UnaryExpr)
462 return tcUnsafeData(n)
463
464 case ir.OUNSAFESTRING:
465 n := n.(*ir.BinaryExpr)
466 return tcUnsafeString(n)
467
468 case ir.OUNSAFESTRINGDATA:
469 n := n.(*ir.UnaryExpr)
470 return tcUnsafeData(n)
471
472 case ir.OITAB:
473 n := n.(*ir.UnaryExpr)
474 return tcITab(n)
475
476 case ir.OIDATA:
477
478
479 n := n.(*ir.UnaryExpr)
480 base.Fatalf("cannot typecheck interface data %v", n)
481 panic("unreachable")
482
483 case ir.OSPTR:
484 n := n.(*ir.UnaryExpr)
485 return tcSPtr(n)
486
487 case ir.OCFUNC:
488 n := n.(*ir.UnaryExpr)
489 n.X = Expr(n.X)
490 n.SetType(types.Types[types.TUINTPTR])
491 return n
492
493 case ir.OGETCALLERSP:
494 n := n.(*ir.CallExpr)
495 if len(n.Args) != 0 {
496 base.FatalfAt(n.Pos(), "unexpected arguments: %v", n)
497 }
498 n.SetType(types.Types[types.TUINTPTR])
499 return n
500
501 case ir.OCONVNOP:
502 n := n.(*ir.ConvExpr)
503 n.X = Expr(n.X)
504 return n
505
506
507 case ir.OAS:
508 n := n.(*ir.AssignStmt)
509 tcAssign(n)
510
511
512 if n.X.Op() == ir.ONAME && ir.IsAutoTmp(n.X) {
513 n.X.Name().Defn = n
514 }
515 return n
516
517 case ir.OAS2:
518 tcAssignList(n.(*ir.AssignListStmt))
519 return n
520
521 case ir.OBREAK,
522 ir.OCONTINUE,
523 ir.ODCL,
524 ir.OGOTO,
525 ir.OFALL:
526 return n
527
528 case ir.OBLOCK:
529 n := n.(*ir.BlockStmt)
530 Stmts(n.List)
531 return n
532
533 case ir.OLABEL:
534 if n.Sym().IsBlank() {
535
536
537
538 n = ir.NewBlockStmt(n.Pos(), nil)
539 }
540 return n
541
542 case ir.ODEFER, ir.OGO:
543 n := n.(*ir.GoDeferStmt)
544 n.Call = typecheck(n.Call, ctxStmt|ctxExpr)
545 tcGoDefer(n)
546 return n
547
548 case ir.OFOR:
549 n := n.(*ir.ForStmt)
550 return tcFor(n)
551
552 case ir.OIF:
553 n := n.(*ir.IfStmt)
554 return tcIf(n)
555
556 case ir.ORETURN:
557 n := n.(*ir.ReturnStmt)
558 return tcReturn(n)
559
560 case ir.OTAILCALL:
561 n := n.(*ir.TailCallStmt)
562 n.Call = typecheck(n.Call, ctxStmt|ctxExpr).(*ir.CallExpr)
563 return n
564
565 case ir.OCHECKNIL:
566 n := n.(*ir.UnaryExpr)
567 return tcCheckNil(n)
568
569 case ir.OSELECT:
570 tcSelect(n.(*ir.SelectStmt))
571 return n
572
573 case ir.OSWITCH:
574 tcSwitch(n.(*ir.SwitchStmt))
575 return n
576
577 case ir.ORANGE:
578 tcRange(n.(*ir.RangeStmt))
579 return n
580
581 case ir.OTYPESW:
582 n := n.(*ir.TypeSwitchGuard)
583 base.Fatalf("use of .(type) outside type switch")
584 return n
585
586 case ir.ODCLFUNC:
587 tcFunc(n.(*ir.Func))
588 return n
589 }
590
591
592
593
594 }
595
596 func typecheckargs(n ir.InitNode) {
597 var list []ir.Node
598 switch n := n.(type) {
599 default:
600 base.Fatalf("typecheckargs %+v", n.Op())
601 case *ir.CallExpr:
602 list = n.Args
603 if n.IsDDD {
604 Exprs(list)
605 return
606 }
607 case *ir.ReturnStmt:
608 list = n.Results
609 }
610 if len(list) != 1 {
611 Exprs(list)
612 return
613 }
614
615 typecheckslice(list, ctxExpr|ctxMultiOK)
616 t := list[0].Type()
617 if t == nil || !t.IsFuncArgStruct() {
618 return
619 }
620
621
622 RewriteMultiValueCall(n, list[0])
623 }
624
625
626
627 func RewriteNonNameCall(n *ir.CallExpr) {
628 np := &n.Fun
629 if dot, ok := (*np).(*ir.SelectorExpr); ok && (dot.Op() == ir.ODOTMETH || dot.Op() == ir.ODOTINTER || dot.Op() == ir.OMETHVALUE) {
630 np = &dot.X
631 }
632
633
634
635
636 if !ir.Any(*np, func(n ir.Node) bool { return n.Op() != ir.ONEW && callOrChan(n) }) {
637 return
638 }
639
640 tmp := TempAt(base.Pos, ir.CurFunc, (*np).Type())
641 as := ir.NewAssignStmt(base.Pos, tmp, *np)
642 as.PtrInit().Append(Stmt(ir.NewDecl(n.Pos(), ir.ODCL, tmp)))
643 *np = tmp
644
645 n.PtrInit().Append(Stmt(as))
646 }
647
648
649
650 func RewriteMultiValueCall(n ir.InitNode, call ir.Node) {
651 as := ir.NewAssignListStmt(base.Pos, ir.OAS2, nil, []ir.Node{call})
652 results := call.Type().Fields()
653 list := make([]ir.Node, len(results))
654 for i, result := range results {
655 tmp := TempAt(base.Pos, ir.CurFunc, result.Type)
656 as.PtrInit().Append(ir.NewDecl(base.Pos, ir.ODCL, tmp))
657 as.Lhs.Append(tmp)
658 list[i] = tmp
659 }
660
661 n.PtrInit().Append(Stmt(as))
662
663 switch n := n.(type) {
664 default:
665 base.Fatalf("RewriteMultiValueCall %+v", n.Op())
666 case *ir.CallExpr:
667 n.Args = list
668 case *ir.ReturnStmt:
669 n.Results = list
670 case *ir.AssignListStmt:
671 if n.Op() != ir.OAS2FUNC {
672 base.Fatalf("RewriteMultiValueCall: invalid op %v", n.Op())
673 }
674 as.SetOp(ir.OAS2FUNC)
675 n.SetOp(ir.OAS2)
676 n.Rhs = make([]ir.Node, len(list))
677 for i, tmp := range list {
678 n.Rhs[i] = AssignConv(tmp, n.Lhs[i].Type(), "assignment")
679 }
680 }
681 }
682
683 func checksliceindex(r ir.Node) bool {
684 t := r.Type()
685 if t == nil {
686 return false
687 }
688 if !t.IsInteger() {
689 base.Errorf("invalid slice index %v (type %v)", r, t)
690 return false
691 }
692 return true
693 }
694
695
696
697
698 func implicitstar(n ir.Node) ir.Node {
699
700 t := n.Type()
701 if t == nil || !t.IsPtr() {
702 return n
703 }
704 t = t.Elem()
705 if t == nil {
706 return n
707 }
708 if !t.IsArray() {
709 return n
710 }
711 star := ir.NewStarExpr(base.Pos, n)
712 star.SetImplicit(true)
713 return Expr(star)
714 }
715
716 func needOneArg(n *ir.CallExpr, f string, args ...interface{}) (ir.Node, bool) {
717 if len(n.Args) == 0 {
718 p := fmt.Sprintf(f, args...)
719 base.Errorf("missing argument to %s: %v", p, n)
720 return nil, false
721 }
722
723 if len(n.Args) > 1 {
724 p := fmt.Sprintf(f, args...)
725 base.Errorf("too many arguments to %s: %v", p, n)
726 return n.Args[0], false
727 }
728
729 return n.Args[0], true
730 }
731
732 func needTwoArgs(n *ir.CallExpr) (ir.Node, ir.Node, bool) {
733 if len(n.Args) != 2 {
734 if len(n.Args) < 2 {
735 base.Errorf("not enough arguments in call to %v", n)
736 } else {
737 base.Errorf("too many arguments in call to %v", n)
738 }
739 return nil, nil, false
740 }
741 return n.Args[0], n.Args[1], true
742 }
743
744
745
746
747
748 func Lookdot1(errnode ir.Node, s *types.Sym, t *types.Type, fs []*types.Field, dostrcmp int) *types.Field {
749 var r *types.Field
750 for _, f := range fs {
751 if dostrcmp != 0 && f.Sym.Name == s.Name {
752 return f
753 }
754 if dostrcmp == 2 && strings.EqualFold(f.Sym.Name, s.Name) {
755 return f
756 }
757 if f.Sym != s {
758 continue
759 }
760 if r != nil {
761 if errnode != nil {
762 base.Errorf("ambiguous selector %v", errnode)
763 } else if t.IsPtr() {
764 base.Errorf("ambiguous selector (%v).%v", t, s)
765 } else {
766 base.Errorf("ambiguous selector %v.%v", t, s)
767 }
768 break
769 }
770
771 r = f
772 }
773
774 return r
775 }
776
777
778
779 func NewMethodExpr(pos src.XPos, recv *types.Type, sym *types.Sym) *ir.SelectorExpr {
780
781 var ms []*types.Field
782 if recv.IsInterface() {
783 ms = recv.AllMethods()
784 } else {
785 mt := types.ReceiverBaseType(recv)
786 if mt == nil {
787 base.FatalfAt(pos, "type %v has no receiver base type", recv)
788 }
789 CalcMethods(mt)
790 ms = mt.AllMethods()
791 }
792
793 m := Lookdot1(nil, sym, recv, ms, 0)
794 if m == nil {
795 base.FatalfAt(pos, "type %v has no method %v", recv, sym)
796 }
797
798 if !types.IsMethodApplicable(recv, m) {
799 base.FatalfAt(pos, "invalid method expression %v.%v (needs pointer receiver)", recv, sym)
800 }
801
802 n := ir.NewSelectorExpr(pos, ir.OMETHEXPR, ir.TypeNode(recv), sym)
803 n.Selection = m
804 n.SetType(NewMethodType(m.Type, recv))
805 n.SetTypecheck(1)
806 return n
807 }
808
809 func derefall(t *types.Type) *types.Type {
810 for t != nil && t.IsPtr() {
811 t = t.Elem()
812 }
813 return t
814 }
815
816
817
818
819
820
821
822 func Lookdot(n *ir.SelectorExpr, t *types.Type, dostrcmp int) *types.Field {
823 s := n.Sel
824
825 types.CalcSize(t)
826 var f1 *types.Field
827 if t.IsStruct() {
828 f1 = Lookdot1(n, s, t, t.Fields(), dostrcmp)
829 } else if t.IsInterface() {
830 f1 = Lookdot1(n, s, t, t.AllMethods(), dostrcmp)
831 }
832
833 var f2 *types.Field
834 if n.X.Type() == t || n.X.Type().Sym() == nil {
835 mt := types.ReceiverBaseType(t)
836 if mt != nil {
837 f2 = Lookdot1(n, s, mt, mt.Methods(), dostrcmp)
838 }
839 }
840
841 if f1 != nil {
842 if dostrcmp > 1 {
843
844 return f1
845 }
846 if f2 != nil {
847 base.Errorf("%v is both field and method", n.Sel)
848 }
849 if f1.Offset == types.BADWIDTH {
850 base.Fatalf("Lookdot badwidth t=%v, f1=%v@%p", t, f1, f1)
851 }
852 n.Selection = f1
853 n.SetType(f1.Type)
854 if t.IsInterface() {
855 if n.X.Type().IsPtr() {
856 star := ir.NewStarExpr(base.Pos, n.X)
857 star.SetImplicit(true)
858 n.X = Expr(star)
859 }
860
861 n.SetOp(ir.ODOTINTER)
862 }
863 return f1
864 }
865
866 if f2 != nil {
867 if dostrcmp > 1 {
868
869 return f2
870 }
871 orig := n.X
872 tt := n.X.Type()
873 types.CalcSize(tt)
874 rcvr := f2.Type.Recv().Type
875 if !types.Identical(rcvr, tt) {
876 if rcvr.IsPtr() && types.Identical(rcvr.Elem(), tt) {
877 checklvalue(n.X, "call pointer method on")
878 addr := NodAddr(n.X)
879 addr.SetImplicit(true)
880 n.X = typecheck(addr, ctxType|ctxExpr)
881 } else if tt.IsPtr() && (!rcvr.IsPtr() || rcvr.IsPtr() && rcvr.Elem().NotInHeap()) && types.Identical(tt.Elem(), rcvr) {
882 star := ir.NewStarExpr(base.Pos, n.X)
883 star.SetImplicit(true)
884 n.X = typecheck(star, ctxType|ctxExpr)
885 } else if tt.IsPtr() && tt.Elem().IsPtr() && types.Identical(derefall(tt), derefall(rcvr)) {
886 base.Errorf("calling method %v with receiver %L requires explicit dereference", n.Sel, n.X)
887 for tt.IsPtr() {
888
889 if rcvr.IsPtr() && !tt.Elem().IsPtr() {
890 break
891 }
892 star := ir.NewStarExpr(base.Pos, n.X)
893 star.SetImplicit(true)
894 n.X = typecheck(star, ctxType|ctxExpr)
895 tt = tt.Elem()
896 }
897 } else {
898 base.Fatalf("method mismatch: %v for %v", rcvr, tt)
899 }
900 }
901
902
903 for x := n.X; ; {
904 var inner ir.Node
905 implicit := false
906 switch x := x.(type) {
907 case *ir.AddrExpr:
908 inner, implicit = x.X, x.Implicit()
909 case *ir.SelectorExpr:
910 inner, implicit = x.X, x.Implicit()
911 case *ir.StarExpr:
912 inner, implicit = x.X, x.Implicit()
913 }
914 if !implicit {
915 break
916 }
917 if inner.Type().Sym() != nil && (x.Op() == ir.ODEREF || x.Op() == ir.ODOTPTR) {
918
919
920 n.X = orig
921 return nil
922 }
923 x = inner
924 }
925
926 n.Selection = f2
927 n.SetType(f2.Type)
928 n.SetOp(ir.ODOTMETH)
929
930 return f2
931 }
932
933 return nil
934 }
935
936 func nokeys(l ir.Nodes) bool {
937 for _, n := range l {
938 if n.Op() == ir.OKEY || n.Op() == ir.OSTRUCTKEY {
939 return false
940 }
941 }
942 return true
943 }
944
945 func hasddd(params []*types.Field) bool {
946
947 for _, tl := range params {
948 if tl.IsDDD() {
949 return true
950 }
951 }
952
953 return false
954 }
955
956
957 func typecheckaste(op ir.Op, call ir.Node, isddd bool, params []*types.Field, nl ir.Nodes, desc func() string) {
958 var t *types.Type
959 var i int
960
961 lno := base.Pos
962 defer func() { base.Pos = lno }()
963
964 var n ir.Node
965 if len(nl) == 1 {
966 n = nl[0]
967 }
968
969 n1 := len(params)
970 n2 := len(nl)
971 if !hasddd(params) {
972 if isddd {
973 goto invalidddd
974 }
975 if n2 > n1 {
976 goto toomany
977 }
978 if n2 < n1 {
979 goto notenough
980 }
981 } else {
982 if !isddd {
983 if n2 < n1-1 {
984 goto notenough
985 }
986 } else {
987 if n2 > n1 {
988 goto toomany
989 }
990 if n2 < n1 {
991 goto notenough
992 }
993 }
994 }
995
996 i = 0
997 for _, tl := range params {
998 t = tl.Type
999 if tl.IsDDD() {
1000 if isddd {
1001 if i >= len(nl) {
1002 goto notenough
1003 }
1004 if len(nl)-i > 1 {
1005 goto toomany
1006 }
1007 n = nl[i]
1008 ir.SetPos(n)
1009 if n.Type() != nil {
1010 nl[i] = assignconvfn(n, t, desc)
1011 }
1012 return
1013 }
1014
1015
1016 for ; i < len(nl); i++ {
1017 n = nl[i]
1018 ir.SetPos(n)
1019 if n.Type() != nil {
1020 nl[i] = assignconvfn(n, t.Elem(), desc)
1021 }
1022 }
1023 return
1024 }
1025
1026 if i >= len(nl) {
1027 goto notenough
1028 }
1029 n = nl[i]
1030 ir.SetPos(n)
1031 if n.Type() != nil {
1032 nl[i] = assignconvfn(n, t, desc)
1033 }
1034 i++
1035 }
1036
1037 if i < len(nl) {
1038 goto toomany
1039 }
1040
1041 invalidddd:
1042 if isddd {
1043 if call != nil {
1044 base.Errorf("invalid use of ... in call to %v", call)
1045 } else {
1046 base.Errorf("invalid use of ... in %v", op)
1047 }
1048 }
1049 return
1050
1051 notenough:
1052 if n == nil || n.Type() != nil {
1053 base.Fatalf("not enough arguments to %v", op)
1054 }
1055 return
1056
1057 toomany:
1058 base.Fatalf("too many arguments to %v", op)
1059 }
1060
1061
1062 func fielddup(name string, hash map[string]bool) {
1063 if hash[name] {
1064 base.Errorf("duplicate field name in struct literal: %s", name)
1065 return
1066 }
1067 hash[name] = true
1068 }
1069
1070
1071 func typecheckarraylit(elemType *types.Type, bound int64, elts []ir.Node, ctx string) int64 {
1072
1073
1074 var indices map[int64]bool
1075 for _, elt := range elts {
1076 if elt.Op() == ir.OKEY {
1077 indices = make(map[int64]bool)
1078 break
1079 }
1080 }
1081
1082 var key, length int64
1083 for i, elt := range elts {
1084 ir.SetPos(elt)
1085 r := elts[i]
1086 var kv *ir.KeyExpr
1087 if elt.Op() == ir.OKEY {
1088 elt := elt.(*ir.KeyExpr)
1089 elt.Key = Expr(elt.Key)
1090 key = IndexConst(elt.Key)
1091 kv = elt
1092 r = elt.Value
1093 }
1094
1095 r = Expr(r)
1096 r = AssignConv(r, elemType, ctx)
1097 if kv != nil {
1098 kv.Value = r
1099 } else {
1100 elts[i] = r
1101 }
1102
1103 if key >= 0 {
1104 if indices != nil {
1105 if indices[key] {
1106 base.Errorf("duplicate index in %s: %d", ctx, key)
1107 } else {
1108 indices[key] = true
1109 }
1110 }
1111
1112 if bound >= 0 && key >= bound {
1113 base.Errorf("array index %d out of bounds [0:%d]", key, bound)
1114 bound = -1
1115 }
1116 }
1117
1118 key++
1119 if key > length {
1120 length = key
1121 }
1122 }
1123
1124 return length
1125 }
1126
1127
1128 func visible(sym *types.Sym) bool {
1129 return sym != nil && (types.IsExported(sym.Name) || sym.Pkg == types.LocalPkg)
1130 }
1131
1132
1133 func nonexported(sym *types.Sym) bool {
1134 return sym != nil && !types.IsExported(sym.Name)
1135 }
1136
1137 func checklvalue(n ir.Node, verb string) {
1138 if !ir.IsAddressable(n) {
1139 base.Errorf("cannot %s %v", verb, n)
1140 }
1141 }
1142
1143 func checkassign(n ir.Node) {
1144
1145 if n.Type() == nil {
1146 if base.Errors() == 0 {
1147 base.Fatalf("expected an error about %v", n)
1148 }
1149 return
1150 }
1151
1152 if ir.IsAddressable(n) {
1153 return
1154 }
1155 if n.Op() == ir.OINDEXMAP {
1156 n := n.(*ir.IndexExpr)
1157 n.Assigned = true
1158 return
1159 }
1160
1161 defer n.SetType(nil)
1162
1163 switch {
1164 case n.Op() == ir.ODOT && n.(*ir.SelectorExpr).X.Op() == ir.OINDEXMAP:
1165 base.Errorf("cannot assign to struct field %v in map", n)
1166 case (n.Op() == ir.OINDEX && n.(*ir.IndexExpr).X.Type().IsString()) || n.Op() == ir.OSLICESTR:
1167 base.Errorf("cannot assign to %v (strings are immutable)", n)
1168 case n.Op() == ir.OLITERAL && n.Sym() != nil && ir.IsConstNode(n):
1169 base.Errorf("cannot assign to %v (declared const)", n)
1170 default:
1171 base.Errorf("cannot assign to %v", n)
1172 }
1173 }
1174
1175 func checkassignto(src *types.Type, dst ir.Node) {
1176
1177 if src == types.UntypedBool && dst.Type().IsBoolean() {
1178 return
1179 }
1180
1181 if op, why := assignOp(src, dst.Type()); op == ir.OXXX {
1182 base.Errorf("cannot assign %v to %L in multiple assignment%s", src, dst, why)
1183 return
1184 }
1185 }
1186
1187
1188
1189
1190 func stringtoruneslit(n *ir.ConvExpr) ir.Node {
1191 if n.X.Op() != ir.OLITERAL || n.X.Val().Kind() != constant.String {
1192 base.Fatalf("stringtoarraylit %v", n)
1193 }
1194
1195 var l []ir.Node
1196 i := 0
1197 for _, r := range ir.StringVal(n.X) {
1198 l = append(l, ir.NewKeyExpr(base.Pos, ir.NewInt(base.Pos, int64(i)), ir.NewInt(base.Pos, int64(r))))
1199 i++
1200 }
1201
1202 return Expr(ir.NewCompLitExpr(base.Pos, ir.OCOMPLIT, n.Type(), l))
1203 }
1204
1205 func checkmake(t *types.Type, arg string, np *ir.Node) bool {
1206 n := *np
1207 if !n.Type().IsInteger() && n.Type().Kind() != types.TIDEAL {
1208 base.Errorf("non-integer %s argument in make(%v) - %v", arg, t, n.Type())
1209 return false
1210 }
1211
1212
1213
1214
1215
1216
1217 n = DefaultLit(n, types.Types[types.TINT])
1218 *np = n
1219
1220 return true
1221 }
1222
1223
1224 func checkunsafesliceorstring(op ir.Op, np *ir.Node) bool {
1225 n := *np
1226 if !n.Type().IsInteger() && n.Type().Kind() != types.TIDEAL {
1227 base.Errorf("non-integer len argument in %v - %v", op, n.Type())
1228 return false
1229 }
1230
1231
1232 n = DefaultLit(n, types.Types[types.TINT])
1233 *np = n
1234
1235 return true
1236 }
1237
1238 func Conv(n ir.Node, t *types.Type) ir.Node {
1239 if types.IdenticalStrict(n.Type(), t) {
1240 return n
1241 }
1242 n = ir.NewConvExpr(base.Pos, ir.OCONV, nil, n)
1243 n.SetType(t)
1244 n = Expr(n)
1245 return n
1246 }
1247
1248
1249
1250 func ConvNop(n ir.Node, t *types.Type) ir.Node {
1251 if types.IdenticalStrict(n.Type(), t) {
1252 return n
1253 }
1254 n = ir.NewConvExpr(base.Pos, ir.OCONVNOP, nil, n)
1255 n.SetType(t)
1256 n = Expr(n)
1257 return n
1258 }
1259
View as plain text