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