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