1
2
3
4
5 package typecheck
6
7 import (
8 "cmd/compile/internal/base"
9 "cmd/compile/internal/ir"
10 "cmd/compile/internal/types"
11 "cmd/internal/src"
12
13 "fmt"
14 "go/constant"
15 "go/token"
16 )
17
18
19 func MakeDotArgs(pos src.XPos, typ *types.Type, args []ir.Node) ir.Node {
20 if len(args) == 0 {
21 return ir.NewNilExpr(pos, typ)
22 }
23
24 args = append([]ir.Node(nil), args...)
25 lit := ir.NewCompLitExpr(pos, ir.OCOMPLIT, typ, args)
26 lit.SetImplicit(true)
27
28 n := Expr(lit)
29 if n.Type() == nil {
30 base.FatalfAt(pos, "mkdotargslice: typecheck failed")
31 }
32 return n
33 }
34
35
36
37 func FixVariadicCall(call *ir.CallExpr) {
38 fntype := call.Fun.Type()
39 if !fntype.IsVariadic() || call.IsDDD {
40 return
41 }
42
43 vi := fntype.NumParams() - 1
44 vt := fntype.Param(vi).Type
45
46 args := call.Args
47 extra := args[vi:]
48 slice := MakeDotArgs(call.Pos(), vt, extra)
49 for i := range extra {
50 extra[i] = nil
51 }
52
53 call.Args = append(args[:vi], slice)
54 call.IsDDD = true
55 }
56
57
58 func FixMethodCall(call *ir.CallExpr) {
59 if call.Fun.Op() != ir.ODOTMETH {
60 return
61 }
62
63 dot := call.Fun.(*ir.SelectorExpr)
64
65 fn := NewMethodExpr(dot.Pos(), dot.X.Type(), dot.Selection.Sym)
66
67 args := make([]ir.Node, 1+len(call.Args))
68 args[0] = dot.X
69 copy(args[1:], call.Args)
70
71 call.SetOp(ir.OCALLFUNC)
72 call.Fun = fn
73 call.Args = args
74 }
75
76 func AssertFixedCall(call *ir.CallExpr) {
77 if call.Fun.Type().IsVariadic() && !call.IsDDD {
78 base.FatalfAt(call.Pos(), "missed FixVariadicCall")
79 }
80 if call.Op() == ir.OCALLMETH {
81 base.FatalfAt(call.Pos(), "missed FixMethodCall")
82 }
83 }
84
85
86
87
88 func ClosureType(clo *ir.ClosureExpr) *types.Type {
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104 fields := make([]*types.Field, 1+len(clo.Func.ClosureVars))
105 fields[0] = types.NewField(base.AutogeneratedPos, types.LocalPkg.Lookup("F"), types.Types[types.TUINTPTR])
106 for i, v := range clo.Func.ClosureVars {
107 typ := v.Type()
108 if !v.Byval() {
109 typ = types.NewPtr(typ)
110 }
111 fields[1+i] = types.NewField(base.AutogeneratedPos, types.LocalPkg.LookupNum("X", i), typ)
112 }
113 typ := types.NewStruct(fields)
114 typ.SetNoalg(true)
115 return typ
116 }
117
118
119
120
121 func MethodValueType(n *ir.SelectorExpr) *types.Type {
122 t := types.NewStruct([]*types.Field{
123 types.NewField(base.Pos, Lookup("F"), types.Types[types.TUINTPTR]),
124 types.NewField(base.Pos, Lookup("R"), n.X.Type()),
125 })
126 t.SetNoalg(true)
127 return t
128 }
129
130
131
132
133 func tcFunc(n *ir.Func) {
134 if base.EnableTrace && base.Flag.LowerT {
135 defer tracePrint("tcFunc", n)(nil)
136 }
137
138 if name := n.Nname; name.Typecheck() == 0 {
139 base.AssertfAt(name.Type() != nil, n.Pos(), "missing type: %v", name)
140 name.SetTypecheck(1)
141 }
142 }
143
144
145 func tcCall(n *ir.CallExpr, top int) ir.Node {
146 Stmts(n.Init())
147 n.Fun = typecheck(n.Fun, ctxExpr|ctxType|ctxCallee)
148
149 l := n.Fun
150
151 if l.Op() == ir.ONAME && l.(*ir.Name).BuiltinOp != 0 {
152 l := l.(*ir.Name)
153 if n.IsDDD && l.BuiltinOp != ir.OAPPEND {
154 base.Errorf("invalid use of ... with builtin %v", l)
155 }
156
157
158 switch l.BuiltinOp {
159 default:
160 base.Fatalf("unknown builtin %v", l)
161
162 case ir.OAPPEND, ir.ODELETE, ir.OMAKE, ir.OMAX, ir.OMIN, ir.OPRINT, ir.OPRINTLN, ir.ORECOVER:
163 n.SetOp(l.BuiltinOp)
164 n.Fun = nil
165 n.SetTypecheck(0)
166 return typecheck(n, top)
167
168 case ir.OCAP, ir.OCLEAR, ir.OCLOSE, ir.OIMAG, ir.OLEN, ir.OPANIC, ir.OREAL, ir.OUNSAFESTRINGDATA, ir.OUNSAFESLICEDATA:
169 typecheckargs(n)
170 fallthrough
171 case ir.ONEW:
172 arg, ok := needOneArg(n, "%v", n.Op())
173 if !ok {
174 n.SetType(nil)
175 return n
176 }
177 u := ir.NewUnaryExpr(n.Pos(), l.BuiltinOp, arg)
178 return typecheck(ir.InitExpr(n.Init(), u), top)
179
180 case ir.OCOMPLEX, ir.OCOPY, ir.OUNSAFEADD, ir.OUNSAFESLICE, ir.OUNSAFESTRING:
181 typecheckargs(n)
182 arg1, arg2, ok := needTwoArgs(n)
183 if !ok {
184 n.SetType(nil)
185 return n
186 }
187 b := ir.NewBinaryExpr(n.Pos(), l.BuiltinOp, arg1, arg2)
188 return typecheck(ir.InitExpr(n.Init(), b), top)
189 }
190 panic("unreachable")
191 }
192
193 n.Fun = DefaultLit(n.Fun, nil)
194 l = n.Fun
195 if l.Op() == ir.OTYPE {
196 if n.IsDDD {
197 base.Fatalf("invalid use of ... in type conversion to %v", l.Type())
198 }
199
200
201 arg, ok := needOneArg(n, "conversion to %v", l.Type())
202 if !ok {
203 n.SetType(nil)
204 return n
205 }
206
207 n := ir.NewConvExpr(n.Pos(), ir.OCONV, nil, arg)
208 n.SetType(l.Type())
209 return tcConv(n)
210 }
211
212 RewriteNonNameCall(n)
213 typecheckargs(n)
214 t := l.Type()
215 if t == nil {
216 n.SetType(nil)
217 return n
218 }
219 types.CheckSize(t)
220
221 switch l.Op() {
222 case ir.ODOTINTER:
223 n.SetOp(ir.OCALLINTER)
224
225 case ir.ODOTMETH:
226 l := l.(*ir.SelectorExpr)
227 n.SetOp(ir.OCALLMETH)
228
229
230
231
232
233 tp := t.Recv().Type
234
235 if l.X == nil || !types.Identical(l.X.Type(), tp) {
236 base.Fatalf("method receiver")
237 }
238
239 default:
240 n.SetOp(ir.OCALLFUNC)
241 if t.Kind() != types.TFUNC {
242 if o := l; o.Name() != nil && types.BuiltinPkg.Lookup(o.Sym().Name).Def != nil {
243
244
245 base.Errorf("cannot call non-function %L, declared at %s",
246 l, base.FmtPos(o.Name().Pos()))
247 } else {
248 base.Errorf("cannot call non-function %L", l)
249 }
250 n.SetType(nil)
251 return n
252 }
253 }
254
255 typecheckaste(ir.OCALL, n.Fun, n.IsDDD, t.Params(), n.Args, func() string { return fmt.Sprintf("argument to %v", n.Fun) })
256 FixVariadicCall(n)
257 FixMethodCall(n)
258 if t.NumResults() == 0 {
259 return n
260 }
261 if t.NumResults() == 1 {
262 n.SetType(l.Type().Result(0).Type)
263
264 if n.Op() == ir.OCALLFUNC && n.Fun.Op() == ir.ONAME {
265 if sym := n.Fun.(*ir.Name).Sym(); types.RuntimeSymName(sym) == "getg" {
266
267
268
269
270
271
272 n.SetOp(ir.OGETG)
273 }
274 }
275 return n
276 }
277
278
279 if top&(ctxMultiOK|ctxStmt) == 0 {
280 base.Errorf("multiple-value %v() in single-value context", l)
281 return n
282 }
283
284 n.SetType(l.Type().ResultsTuple())
285 return n
286 }
287
288
289 func tcAppend(n *ir.CallExpr) ir.Node {
290 typecheckargs(n)
291 args := n.Args
292 if len(args) == 0 {
293 base.Errorf("missing arguments to append")
294 n.SetType(nil)
295 return n
296 }
297
298 t := args[0].Type()
299 if t == nil {
300 n.SetType(nil)
301 return n
302 }
303
304 n.SetType(t)
305 if !t.IsSlice() {
306 if ir.IsNil(args[0]) {
307 base.Errorf("first argument to append must be typed slice; have untyped nil")
308 n.SetType(nil)
309 return n
310 }
311
312 base.Errorf("first argument to append must be slice; have %L", t)
313 n.SetType(nil)
314 return n
315 }
316
317 if n.IsDDD {
318 if len(args) == 1 {
319 base.Errorf("cannot use ... on first argument to append")
320 n.SetType(nil)
321 return n
322 }
323
324 if len(args) != 2 {
325 base.Errorf("too many arguments to append")
326 n.SetType(nil)
327 return n
328 }
329
330
331
332
333
334
335 return n
336 }
337
338 as := args[1:]
339 for i, n := range as {
340 if n.Type() == nil {
341 continue
342 }
343 as[i] = AssignConv(n, t.Elem(), "append")
344 types.CheckSize(as[i].Type())
345 }
346 return n
347 }
348
349
350 func tcClear(n *ir.UnaryExpr) ir.Node {
351 n.X = Expr(n.X)
352 n.X = DefaultLit(n.X, nil)
353 l := n.X
354 t := l.Type()
355 if t == nil {
356 n.SetType(nil)
357 return n
358 }
359
360 switch {
361 case t.IsMap(), t.IsSlice():
362 default:
363 base.Errorf("invalid operation: %v (argument must be a map or slice)", n)
364 n.SetType(nil)
365 return n
366 }
367
368 return n
369 }
370
371
372 func tcClose(n *ir.UnaryExpr) ir.Node {
373 n.X = Expr(n.X)
374 n.X = DefaultLit(n.X, nil)
375 l := n.X
376 t := l.Type()
377 if t == nil {
378 n.SetType(nil)
379 return n
380 }
381 if !t.IsChan() {
382 base.Errorf("invalid operation: %v (non-chan type %v)", n, t)
383 n.SetType(nil)
384 return n
385 }
386
387 if !t.ChanDir().CanSend() {
388 base.Errorf("invalid operation: %v (cannot close receive-only channel)", n)
389 n.SetType(nil)
390 return n
391 }
392 return n
393 }
394
395
396 func tcComplex(n *ir.BinaryExpr) ir.Node {
397 l := Expr(n.X)
398 r := Expr(n.Y)
399 if l.Type() == nil || r.Type() == nil {
400 n.SetType(nil)
401 return n
402 }
403 l, r = defaultlit2(l, r, false)
404 if l.Type() == nil || r.Type() == nil {
405 n.SetType(nil)
406 return n
407 }
408 n.X = l
409 n.Y = r
410
411 if !types.Identical(l.Type(), r.Type()) {
412 base.Errorf("invalid operation: %v (mismatched types %v and %v)", n, l.Type(), r.Type())
413 n.SetType(nil)
414 return n
415 }
416
417 var t *types.Type
418 switch l.Type().Kind() {
419 default:
420 base.Errorf("invalid operation: %v (arguments have type %v, expected floating-point)", n, l.Type())
421 n.SetType(nil)
422 return n
423
424 case types.TIDEAL:
425 t = types.UntypedComplex
426
427 case types.TFLOAT32:
428 t = types.Types[types.TCOMPLEX64]
429
430 case types.TFLOAT64:
431 t = types.Types[types.TCOMPLEX128]
432 }
433 n.SetType(t)
434 return n
435 }
436
437
438 func tcCopy(n *ir.BinaryExpr) ir.Node {
439 n.SetType(types.Types[types.TINT])
440 n.X = Expr(n.X)
441 n.X = DefaultLit(n.X, nil)
442 n.Y = Expr(n.Y)
443 n.Y = DefaultLit(n.Y, nil)
444 if n.X.Type() == nil || n.Y.Type() == nil {
445 n.SetType(nil)
446 return n
447 }
448
449
450 if n.X.Type().IsSlice() && n.Y.Type().IsString() {
451 if types.Identical(n.X.Type().Elem(), types.ByteType) {
452 return n
453 }
454 base.Errorf("arguments to copy have different element types: %L and string", n.X.Type())
455 n.SetType(nil)
456 return n
457 }
458
459 if !n.X.Type().IsSlice() || !n.Y.Type().IsSlice() {
460 if !n.X.Type().IsSlice() && !n.Y.Type().IsSlice() {
461 base.Errorf("arguments to copy must be slices; have %L, %L", n.X.Type(), n.Y.Type())
462 } else if !n.X.Type().IsSlice() {
463 base.Errorf("first argument to copy should be slice; have %L", n.X.Type())
464 } else {
465 base.Errorf("second argument to copy should be slice or string; have %L", n.Y.Type())
466 }
467 n.SetType(nil)
468 return n
469 }
470
471 if !types.Identical(n.X.Type().Elem(), n.Y.Type().Elem()) {
472 base.Errorf("arguments to copy have different element types: %L and %L", n.X.Type(), n.Y.Type())
473 n.SetType(nil)
474 return n
475 }
476 return n
477 }
478
479
480 func tcDelete(n *ir.CallExpr) ir.Node {
481 typecheckargs(n)
482 args := n.Args
483 if len(args) == 0 {
484 base.Errorf("missing arguments to delete")
485 n.SetType(nil)
486 return n
487 }
488
489 if len(args) == 1 {
490 base.Errorf("missing second (key) argument to delete")
491 n.SetType(nil)
492 return n
493 }
494
495 if len(args) != 2 {
496 base.Errorf("too many arguments to delete")
497 n.SetType(nil)
498 return n
499 }
500
501 l := args[0]
502 r := args[1]
503 if l.Type() != nil && !l.Type().IsMap() {
504 base.Errorf("first argument to delete must be map; have %L", l.Type())
505 n.SetType(nil)
506 return n
507 }
508
509 args[1] = AssignConv(r, l.Type().Key(), "delete")
510 return n
511 }
512
513
514 func tcMake(n *ir.CallExpr) ir.Node {
515 args := n.Args
516 if len(args) == 0 {
517 base.Errorf("missing argument to make")
518 n.SetType(nil)
519 return n
520 }
521
522 n.Args = nil
523 l := args[0]
524 l = typecheck(l, ctxType)
525 t := l.Type()
526 if t == nil {
527 n.SetType(nil)
528 return n
529 }
530
531 i := 1
532 var nn ir.Node
533 switch t.Kind() {
534 default:
535 base.Errorf("cannot make type %v", t)
536 n.SetType(nil)
537 return n
538
539 case types.TSLICE:
540 if i >= len(args) {
541 base.Errorf("missing len argument to make(%v)", t)
542 n.SetType(nil)
543 return n
544 }
545
546 l = args[i]
547 i++
548 l = Expr(l)
549 var r ir.Node
550 if i < len(args) {
551 r = args[i]
552 i++
553 r = Expr(r)
554 }
555
556 if l.Type() == nil || (r != nil && r.Type() == nil) {
557 n.SetType(nil)
558 return n
559 }
560 if !checkmake(t, "len", &l) || r != nil && !checkmake(t, "cap", &r) {
561 n.SetType(nil)
562 return n
563 }
564 if ir.IsConst(l, constant.Int) && r != nil && ir.IsConst(r, constant.Int) && constant.Compare(l.Val(), token.GTR, r.Val()) {
565 base.Errorf("len larger than cap in make(%v)", t)
566 n.SetType(nil)
567 return n
568 }
569 nn = ir.NewMakeExpr(n.Pos(), ir.OMAKESLICE, l, r)
570
571 case types.TMAP:
572 if i < len(args) {
573 l = args[i]
574 i++
575 l = Expr(l)
576 l = DefaultLit(l, types.Types[types.TINT])
577 if l.Type() == nil {
578 n.SetType(nil)
579 return n
580 }
581 if !checkmake(t, "size", &l) {
582 n.SetType(nil)
583 return n
584 }
585 } else {
586 l = ir.NewInt(base.Pos, 0)
587 }
588 nn = ir.NewMakeExpr(n.Pos(), ir.OMAKEMAP, l, nil)
589 nn.SetEsc(n.Esc())
590
591 case types.TCHAN:
592 l = nil
593 if i < len(args) {
594 l = args[i]
595 i++
596 l = Expr(l)
597 l = DefaultLit(l, types.Types[types.TINT])
598 if l.Type() == nil {
599 n.SetType(nil)
600 return n
601 }
602 if !checkmake(t, "buffer", &l) {
603 n.SetType(nil)
604 return n
605 }
606 } else {
607 l = ir.NewInt(base.Pos, 0)
608 }
609 nn = ir.NewMakeExpr(n.Pos(), ir.OMAKECHAN, l, nil)
610 }
611
612 if i < len(args) {
613 base.Errorf("too many arguments to make(%v)", t)
614 n.SetType(nil)
615 return n
616 }
617
618 nn.SetType(t)
619 return nn
620 }
621
622
623 func tcMakeSliceCopy(n *ir.MakeExpr) ir.Node {
624
625
626
627
628 t := n.Type()
629
630 if t == nil {
631 base.Fatalf("no type specified for OMAKESLICECOPY")
632 }
633
634 if !t.IsSlice() {
635 base.Fatalf("invalid type %v for OMAKESLICECOPY", n.Type())
636 }
637
638 if n.Len == nil {
639 base.Fatalf("missing len argument for OMAKESLICECOPY")
640 }
641
642 if n.Cap == nil {
643 base.Fatalf("missing slice argument to copy for OMAKESLICECOPY")
644 }
645
646 n.Len = Expr(n.Len)
647 n.Cap = Expr(n.Cap)
648
649 n.Len = DefaultLit(n.Len, types.Types[types.TINT])
650
651 if !n.Len.Type().IsInteger() && n.Type().Kind() != types.TIDEAL {
652 base.Errorf("non-integer len argument in OMAKESLICECOPY")
653 }
654
655 if ir.IsConst(n.Len, constant.Int) {
656 if ir.ConstOverflow(n.Len.Val(), types.Types[types.TINT]) {
657 base.Fatalf("len for OMAKESLICECOPY too large")
658 }
659 if constant.Sign(n.Len.Val()) < 0 {
660 base.Fatalf("len for OMAKESLICECOPY must be non-negative")
661 }
662 }
663 return n
664 }
665
666
667 func tcNew(n *ir.UnaryExpr) ir.Node {
668 if n.X == nil {
669
670
671 base.Fatalf("missing argument to new")
672 }
673 l := n.X
674 l = typecheck(l, ctxType)
675 t := l.Type()
676 if t == nil {
677 n.SetType(nil)
678 return n
679 }
680 n.X = l
681 n.SetType(types.NewPtr(t))
682 return n
683 }
684
685
686 func tcPanic(n *ir.UnaryExpr) ir.Node {
687 n.X = Expr(n.X)
688 n.X = AssignConv(n.X, types.Types[types.TINTER], "argument to panic")
689 if n.X.Type() == nil {
690 n.SetType(nil)
691 return n
692 }
693 return n
694 }
695
696
697 func tcPrint(n *ir.CallExpr) ir.Node {
698 typecheckargs(n)
699 ls := n.Args
700 for i1, n1 := range ls {
701
702 if ir.IsConst(n1, constant.Int) {
703 ls[i1] = DefaultLit(ls[i1], types.Types[types.TINT64])
704 } else {
705 ls[i1] = DefaultLit(ls[i1], nil)
706 }
707 }
708 return n
709 }
710
711
712 func tcMinMax(n *ir.CallExpr) ir.Node {
713 typecheckargs(n)
714 arg0 := n.Args[0]
715 for _, arg := range n.Args[1:] {
716 if !types.Identical(arg.Type(), arg0.Type()) {
717 base.FatalfAt(n.Pos(), "mismatched arguments: %L and %L", arg0, arg)
718 }
719 }
720 n.SetType(arg0.Type())
721 return n
722 }
723
724
725 func tcRealImag(n *ir.UnaryExpr) ir.Node {
726 n.X = Expr(n.X)
727 l := n.X
728 t := l.Type()
729 if t == nil {
730 n.SetType(nil)
731 return n
732 }
733
734
735 switch t.Kind() {
736 case types.TIDEAL:
737 n.SetType(types.UntypedFloat)
738 case types.TCOMPLEX64:
739 n.SetType(types.Types[types.TFLOAT32])
740 case types.TCOMPLEX128:
741 n.SetType(types.Types[types.TFLOAT64])
742 default:
743 base.Errorf("invalid argument %L for %v", l, n.Op())
744 n.SetType(nil)
745 return n
746 }
747 return n
748 }
749
750
751 func tcRecover(n *ir.CallExpr) ir.Node {
752 if len(n.Args) != 0 {
753 base.Errorf("too many arguments to recover")
754 n.SetType(nil)
755 return n
756 }
757
758
759 var fp ir.Node = ir.NewCallExpr(n.Pos(), ir.OGETCALLERSP, nil, nil)
760 if off := base.Ctxt.Arch.FixedFrameSize; off != 0 {
761 fp = ir.NewBinaryExpr(n.Pos(), ir.OADD, fp, ir.NewInt(base.Pos, off))
762 }
763
764 fp = ir.NewConvExpr(n.Pos(), ir.OCONVNOP, types.NewPtr(types.Types[types.TINT32]), fp)
765
766 n.SetOp(ir.ORECOVERFP)
767 n.SetType(types.Types[types.TINTER])
768 n.Args = []ir.Node{Expr(fp)}
769 return n
770 }
771
772
773 func tcUnsafeAdd(n *ir.BinaryExpr) *ir.BinaryExpr {
774 n.X = AssignConv(Expr(n.X), types.Types[types.TUNSAFEPTR], "argument to unsafe.Add")
775 n.Y = DefaultLit(Expr(n.Y), types.Types[types.TINT])
776 if n.X.Type() == nil || n.Y.Type() == nil {
777 n.SetType(nil)
778 return n
779 }
780 if !n.Y.Type().IsInteger() {
781 n.SetType(nil)
782 return n
783 }
784 n.SetType(n.X.Type())
785 return n
786 }
787
788
789 func tcUnsafeSlice(n *ir.BinaryExpr) *ir.BinaryExpr {
790 n.X = Expr(n.X)
791 n.Y = Expr(n.Y)
792 if n.X.Type() == nil || n.Y.Type() == nil {
793 n.SetType(nil)
794 return n
795 }
796 t := n.X.Type()
797 if !t.IsPtr() {
798 base.Errorf("first argument to unsafe.Slice must be pointer; have %L", t)
799 } else if t.Elem().NotInHeap() {
800
801
802
803
804 base.Errorf("unsafe.Slice of incomplete (or unallocatable) type not allowed")
805 }
806
807 if !checkunsafesliceorstring(n.Op(), &n.Y) {
808 n.SetType(nil)
809 return n
810 }
811 n.SetType(types.NewSlice(t.Elem()))
812 return n
813 }
814
815
816 func tcUnsafeString(n *ir.BinaryExpr) *ir.BinaryExpr {
817 n.X = Expr(n.X)
818 n.Y = Expr(n.Y)
819 if n.X.Type() == nil || n.Y.Type() == nil {
820 n.SetType(nil)
821 return n
822 }
823 t := n.X.Type()
824 if !t.IsPtr() || !types.Identical(t.Elem(), types.Types[types.TUINT8]) {
825 base.Errorf("first argument to unsafe.String must be *byte; have %L", t)
826 }
827
828 if !checkunsafesliceorstring(n.Op(), &n.Y) {
829 n.SetType(nil)
830 return n
831 }
832 n.SetType(types.Types[types.TSTRING])
833 return n
834 }
835
View as plain text