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
12 "fmt"
13 "go/constant"
14 "go/token"
15 )
16
17
18 func MakeDotArgs(typ *types.Type, args []ir.Node) ir.Node {
19 var n ir.Node
20 if len(args) == 0 {
21 n = NodNil()
22 n.SetType(typ)
23 } else {
24 lit := ir.NewCompLitExpr(base.Pos, ir.OCOMPLIT, ir.TypeNode(typ), nil)
25 lit.List.Append(args...)
26 lit.SetImplicit(true)
27 n = lit
28 }
29
30 n = Expr(n)
31 if n.Type() == nil {
32 base.Fatalf("mkdotargslice: typecheck failed")
33 }
34 return n
35 }
36
37
38
39 func FixVariadicCall(call *ir.CallExpr) {
40 fntype := call.X.Type()
41 if !fntype.IsVariadic() || call.IsDDD {
42 return
43 }
44
45 vi := fntype.NumParams() - 1
46 vt := fntype.Params().Field(vi).Type
47
48 args := call.Args
49 extra := args[vi:]
50 slice := MakeDotArgs(vt, extra)
51 for i := range extra {
52 extra[i] = nil
53 }
54
55 call.Args = append(args[:vi], slice)
56 call.IsDDD = true
57 }
58
59
60
61
62 func ClosureType(clo *ir.ClosureExpr) *types.Type {
63
64
65
66
67
68
69
70
71
72
73
74
75
76 fields := []*types.Field{
77 types.NewField(base.Pos, Lookup(".F"), types.Types[types.TUINTPTR]),
78 }
79 for _, v := range clo.Func.ClosureVars {
80 typ := v.Type()
81 if !v.Byval() {
82 typ = types.NewPtr(typ)
83 }
84 fields = append(fields, types.NewField(base.Pos, v.Sym(), typ))
85 }
86 typ := types.NewStruct(types.NoPkg, fields)
87 typ.SetNoalg(true)
88 return typ
89 }
90
91
92
93
94 func PartialCallType(n *ir.SelectorExpr) *types.Type {
95 t := types.NewStruct(types.NoPkg, []*types.Field{
96 types.NewField(base.Pos, Lookup("F"), types.Types[types.TUINTPTR]),
97 types.NewField(base.Pos, Lookup("R"), n.X.Type()),
98 })
99 t.SetNoalg(true)
100 return t
101 }
102
103
104
105
106 var inTypeCheckInl bool
107
108
109
110
111 func ImportedBody(fn *ir.Func) {
112 if fn.Inl.Body != nil {
113 return
114 }
115 lno := ir.SetPos(fn.Nname)
116
117
118
119
120
121
122
123 IncrementalAddrtaken = false
124 defer func() {
125 if DirtyAddrtaken {
126 ComputeAddrtaken(fn.Inl.Body)
127 DirtyAddrtaken = false
128 }
129 IncrementalAddrtaken = true
130 }()
131
132 ImportBody(fn)
133
134
135
136
137
138 pkg := fnpkg(fn.Nname)
139
140 if pkg == types.LocalPkg || pkg == nil {
141 return
142 }
143
144 if base.Flag.LowerM > 2 || base.Debug.Export != 0 {
145 fmt.Printf("typecheck import [%v] %L { %v }\n", fn.Sym(), fn, ir.Nodes(fn.Inl.Body))
146 }
147
148 if !go117ExportTypes {
149
150 savefn := ir.CurFunc
151 ir.CurFunc = fn
152 if inTypeCheckInl {
153 base.Fatalf("inTypeCheckInl should not be set recursively")
154 }
155 inTypeCheckInl = true
156 Stmts(fn.Inl.Body)
157 inTypeCheckInl = false
158 ir.CurFunc = savefn
159 }
160
161 base.Pos = lno
162 }
163
164
165
166 func fnpkg(fn *ir.Name) *types.Pkg {
167 if ir.IsMethod(fn) {
168
169 rcvr := fn.Type().Recv().Type
170
171 if rcvr.IsPtr() {
172 rcvr = rcvr.Elem()
173 }
174 if rcvr.Sym() == nil {
175 base.Fatalf("receiver with no sym: [%v] %L (%v)", fn.Sym(), fn, rcvr)
176 }
177 return rcvr.Sym().Pkg
178 }
179
180
181 return fn.Sym().Pkg
182 }
183
184
185
186 func ClosureName(outerfunc *ir.Func) *types.Sym {
187 outer := "glob."
188 prefix := "func"
189 gen := &globClosgen
190
191 if outerfunc != nil {
192 if outerfunc.OClosure != nil {
193 prefix = ""
194 }
195
196 outer = ir.FuncName(outerfunc)
197
198
199
200
201 if !ir.IsBlank(outerfunc.Nname) {
202 gen = &outerfunc.Closgen
203 }
204 }
205
206 *gen++
207 return Lookup(fmt.Sprintf("%s.%s%d", outer, prefix, *gen))
208 }
209
210
211 var globClosgen int32
212
213
214
215
216
217
218
219 func MethodValueWrapper(dot *ir.SelectorExpr) *ir.Func {
220 if dot.Op() != ir.OCALLPART {
221 base.Fatalf("MethodValueWrapper: unexpected %v (%v)", dot, dot.Op())
222 }
223
224 t0 := dot.Type()
225 meth := dot.Sel
226 rcvrtype := dot.X.Type()
227 sym := ir.MethodSymSuffix(rcvrtype, meth, "-fm")
228
229 if sym.Uniq() {
230 return sym.Def.(*ir.Func)
231 }
232 sym.SetUniq(true)
233
234 savecurfn := ir.CurFunc
235 saveLineNo := base.Pos
236 ir.CurFunc = nil
237
238
239 if pos := dot.Selection.Pos; pos.IsKnown() {
240 base.Pos = pos
241 }
242
243
244
245
246
247
248 tfn := ir.NewFuncType(base.Pos, nil,
249 NewFuncParams(t0.Params(), true),
250 NewFuncParams(t0.Results(), false))
251
252 fn := DeclFunc(sym, tfn)
253 fn.SetDupok(true)
254 fn.SetNeedctxt(true)
255 fn.SetWrapper(true)
256
257
258 ptr := ir.NewNameAt(base.Pos, Lookup(".this"))
259 ptr.Class = ir.PAUTOHEAP
260 ptr.SetType(rcvrtype)
261 ptr.Curfn = fn
262 ptr.SetIsClosureVar(true)
263 ptr.SetByval(true)
264 fn.ClosureVars = append(fn.ClosureVars, ptr)
265
266 call := ir.NewCallExpr(base.Pos, ir.OCALL, ir.NewSelectorExpr(base.Pos, ir.OXDOT, ptr, meth), nil)
267 call.Args = ir.ParamNames(tfn.Type())
268 call.IsDDD = tfn.Type().IsVariadic()
269
270 var body ir.Node = call
271 if t0.NumResults() != 0 {
272 ret := ir.NewReturnStmt(base.Pos, nil)
273 ret.Results = []ir.Node{call}
274 body = ret
275 }
276
277 fn.Body = []ir.Node{body}
278 FinishFuncBody()
279
280 Func(fn)
281
282
283 ir.CurFunc = fn
284 Stmts(fn.Body)
285 sym.Def = fn
286 Target.Decls = append(Target.Decls, fn)
287 ir.CurFunc = savecurfn
288 base.Pos = saveLineNo
289
290 return fn
291 }
292
293
294
295
296
297 func tcClosure(clo *ir.ClosureExpr, top int) {
298 fn := clo.Func
299
300
301 if x := getIotaValue(); x >= 0 {
302 fn.Iota = x
303 }
304
305 fn.SetClosureCalled(top&ctxCallee != 0)
306
307
308
309
310 if fn.Typecheck() == 1 {
311 clo.SetType(fn.Type())
312 return
313 }
314
315
316
317
318
319 if !inTypeCheckInl {
320 fn.Nname.SetSym(ClosureName(ir.CurFunc))
321 ir.MarkFunc(fn.Nname)
322 }
323 Func(fn)
324 clo.SetType(fn.Type())
325
326
327
328
329
330 if ir.CurFunc != nil && clo.Type() != nil {
331 oldfn := ir.CurFunc
332 ir.CurFunc = fn
333 Stmts(fn.Body)
334 ir.CurFunc = oldfn
335 }
336
337 out := 0
338 for _, v := range fn.ClosureVars {
339 if v.Type() == nil {
340
341
342
343
344 continue
345 }
346
347
348
349 Expr(v.Outer)
350
351 fn.ClosureVars[out] = v
352 out++
353 }
354 fn.ClosureVars = fn.ClosureVars[:out]
355
356 if base.Flag.W > 1 {
357 s := fmt.Sprintf("New closure func: %s", ir.FuncName(fn))
358 ir.Dump(s, fn)
359 }
360 if !inTypeCheckInl {
361
362 Target.Decls = append(Target.Decls, fn)
363 }
364 }
365
366
367
368
369 func tcFunc(n *ir.Func) {
370 if base.EnableTrace && base.Flag.LowerT {
371 defer tracePrint("tcFunc", n)(nil)
372 }
373
374 n.Nname = AssignExpr(n.Nname).(*ir.Name)
375 t := n.Nname.Type()
376 if t == nil {
377 return
378 }
379 rcvr := t.Recv()
380 if rcvr != nil && n.Shortname != nil {
381 m := addmethod(n, n.Shortname, t, true, n.Pragma&ir.Nointerface != 0)
382 if m == nil {
383 return
384 }
385
386 n.Nname.SetSym(ir.MethodSym(rcvr.Type, n.Shortname))
387 Declare(n.Nname, ir.PFUNC)
388 }
389 }
390
391
392 func tcCall(n *ir.CallExpr, top int) ir.Node {
393 n.Use = ir.CallUseExpr
394 if top == ctxStmt {
395 n.Use = ir.CallUseStmt
396 }
397 Stmts(n.Init())
398 n.X = typecheck(n.X, ctxExpr|ctxType|ctxCallee)
399 if n.X.Diag() {
400 n.SetDiag(true)
401 }
402
403 l := n.X
404
405 if l.Op() == ir.ONAME && l.(*ir.Name).BuiltinOp != 0 {
406 l := l.(*ir.Name)
407 if n.IsDDD && l.BuiltinOp != ir.OAPPEND {
408 base.Errorf("invalid use of ... with builtin %v", l)
409 }
410
411
412 switch l.BuiltinOp {
413 default:
414 base.Fatalf("unknown builtin %v", l)
415
416 case ir.OAPPEND, ir.ODELETE, ir.OMAKE, ir.OPRINT, ir.OPRINTN, ir.ORECOVER:
417 n.SetOp(l.BuiltinOp)
418 n.X = nil
419 n.SetTypecheck(0)
420 return typecheck(n, top)
421
422 case ir.OCAP, ir.OCLOSE, ir.OIMAG, ir.OLEN, ir.OPANIC, ir.OREAL:
423 typecheckargs(n)
424 fallthrough
425 case ir.ONEW, ir.OALIGNOF, ir.OOFFSETOF, ir.OSIZEOF:
426 arg, ok := needOneArg(n, "%v", n.Op())
427 if !ok {
428 n.SetType(nil)
429 return n
430 }
431 u := ir.NewUnaryExpr(n.Pos(), l.BuiltinOp, arg)
432 return typecheck(ir.InitExpr(n.Init(), u), top)
433
434 case ir.OCOMPLEX, ir.OCOPY, ir.OUNSAFEADD, ir.OUNSAFESLICE:
435 typecheckargs(n)
436 arg1, arg2, ok := needTwoArgs(n)
437 if !ok {
438 n.SetType(nil)
439 return n
440 }
441 b := ir.NewBinaryExpr(n.Pos(), l.BuiltinOp, arg1, arg2)
442 return typecheck(ir.InitExpr(n.Init(), b), top)
443 }
444 panic("unreachable")
445 }
446
447 n.X = DefaultLit(n.X, nil)
448 l = n.X
449 if l.Op() == ir.OTYPE {
450 if n.IsDDD {
451 if !l.Type().Broke() {
452 base.Errorf("invalid use of ... in type conversion to %v", l.Type())
453 }
454 n.SetDiag(true)
455 }
456
457
458 arg, ok := needOneArg(n, "conversion to %v", l.Type())
459 if !ok {
460 n.SetType(nil)
461 return n
462 }
463
464 n := ir.NewConvExpr(n.Pos(), ir.OCONV, nil, arg)
465 n.SetType(l.Type())
466 return tcConv(n)
467 }
468
469 typecheckargs(n)
470 t := l.Type()
471 if t == nil {
472 n.SetType(nil)
473 return n
474 }
475 types.CheckSize(t)
476
477 switch l.Op() {
478 case ir.ODOTINTER:
479 n.SetOp(ir.OCALLINTER)
480
481 case ir.ODOTMETH:
482 l := l.(*ir.SelectorExpr)
483 n.SetOp(ir.OCALLMETH)
484
485
486
487
488
489 tp := t.Recv().Type
490
491 if l.X == nil || !types.Identical(l.X.Type(), tp) {
492 base.Fatalf("method receiver")
493 }
494
495 default:
496 n.SetOp(ir.OCALLFUNC)
497 if t.Kind() != types.TFUNC {
498 if o := ir.Orig(l); o.Name() != nil && types.BuiltinPkg.Lookup(o.Sym().Name).Def != nil {
499
500
501 base.Errorf("cannot call non-function %L, declared at %s",
502 l, base.FmtPos(o.Name().Pos()))
503 } else {
504 base.Errorf("cannot call non-function %L", l)
505 }
506 n.SetType(nil)
507 return n
508 }
509 }
510
511 typecheckaste(ir.OCALL, n.X, n.IsDDD, t.Params(), n.Args, func() string { return fmt.Sprintf("argument to %v", n.X) })
512 if t.NumResults() == 0 {
513 return n
514 }
515 if t.NumResults() == 1 {
516 n.SetType(l.Type().Results().Field(0).Type)
517
518 if n.Op() == ir.OCALLFUNC && n.X.Op() == ir.ONAME {
519 if sym := n.X.(*ir.Name).Sym(); types.IsRuntimePkg(sym.Pkg) && sym.Name == "getg" {
520
521
522
523
524
525
526 n.SetOp(ir.OGETG)
527 }
528 }
529 return n
530 }
531
532
533 if top&(ctxMultiOK|ctxStmt) == 0 {
534 base.Errorf("multiple-value %v() in single-value context", l)
535 return n
536 }
537
538 n.SetType(l.Type().Results())
539 return n
540 }
541
542
543 func tcAppend(n *ir.CallExpr) ir.Node {
544 typecheckargs(n)
545 args := n.Args
546 if len(args) == 0 {
547 base.Errorf("missing arguments to append")
548 n.SetType(nil)
549 return n
550 }
551
552 t := args[0].Type()
553 if t == nil {
554 n.SetType(nil)
555 return n
556 }
557
558 n.SetType(t)
559 if !t.IsSlice() {
560 if ir.IsNil(args[0]) {
561 base.Errorf("first argument to append must be typed slice; have untyped nil")
562 n.SetType(nil)
563 return n
564 }
565
566 base.Errorf("first argument to append must be slice; have %L", t)
567 n.SetType(nil)
568 return n
569 }
570
571 if n.IsDDD {
572 if len(args) == 1 {
573 base.Errorf("cannot use ... on first argument to append")
574 n.SetType(nil)
575 return n
576 }
577
578 if len(args) != 2 {
579 base.Errorf("too many arguments to append")
580 n.SetType(nil)
581 return n
582 }
583
584 if t.Elem().IsKind(types.TUINT8) && args[1].Type().IsString() {
585 args[1] = DefaultLit(args[1], types.Types[types.TSTRING])
586 return n
587 }
588
589 args[1] = AssignConv(args[1], t.Underlying(), "append")
590 return n
591 }
592
593 as := args[1:]
594 for i, n := range as {
595 if n.Type() == nil {
596 continue
597 }
598 as[i] = AssignConv(n, t.Elem(), "append")
599 types.CheckSize(as[i].Type())
600 }
601 return n
602 }
603
604
605 func tcClose(n *ir.UnaryExpr) ir.Node {
606 n.X = Expr(n.X)
607 n.X = DefaultLit(n.X, nil)
608 l := n.X
609 t := l.Type()
610 if t == nil {
611 n.SetType(nil)
612 return n
613 }
614 if !t.IsChan() {
615 base.Errorf("invalid operation: %v (non-chan type %v)", n, t)
616 n.SetType(nil)
617 return n
618 }
619
620 if !t.ChanDir().CanSend() {
621 base.Errorf("invalid operation: %v (cannot close receive-only channel)", n)
622 n.SetType(nil)
623 return n
624 }
625 return n
626 }
627
628
629 func tcComplex(n *ir.BinaryExpr) ir.Node {
630 l := Expr(n.X)
631 r := Expr(n.Y)
632 if l.Type() == nil || r.Type() == nil {
633 n.SetType(nil)
634 return n
635 }
636 l, r = defaultlit2(l, r, false)
637 if l.Type() == nil || r.Type() == nil {
638 n.SetType(nil)
639 return n
640 }
641 n.X = l
642 n.Y = r
643
644 if !types.Identical(l.Type(), r.Type()) {
645 base.Errorf("invalid operation: %v (mismatched types %v and %v)", n, l.Type(), r.Type())
646 n.SetType(nil)
647 return n
648 }
649
650 var t *types.Type
651 switch l.Type().Kind() {
652 default:
653 base.Errorf("invalid operation: %v (arguments have type %v, expected floating-point)", n, l.Type())
654 n.SetType(nil)
655 return n
656
657 case types.TIDEAL:
658 t = types.UntypedComplex
659
660 case types.TFLOAT32:
661 t = types.Types[types.TCOMPLEX64]
662
663 case types.TFLOAT64:
664 t = types.Types[types.TCOMPLEX128]
665 }
666 n.SetType(t)
667 return n
668 }
669
670
671 func tcCopy(n *ir.BinaryExpr) ir.Node {
672 n.SetType(types.Types[types.TINT])
673 n.X = Expr(n.X)
674 n.X = DefaultLit(n.X, nil)
675 n.Y = Expr(n.Y)
676 n.Y = DefaultLit(n.Y, nil)
677 if n.X.Type() == nil || n.Y.Type() == nil {
678 n.SetType(nil)
679 return n
680 }
681
682
683 if n.X.Type().IsSlice() && n.Y.Type().IsString() {
684 if types.Identical(n.X.Type().Elem(), types.ByteType) {
685 return n
686 }
687 base.Errorf("arguments to copy have different element types: %L and string", n.X.Type())
688 n.SetType(nil)
689 return n
690 }
691
692 if !n.X.Type().IsSlice() || !n.Y.Type().IsSlice() {
693 if !n.X.Type().IsSlice() && !n.Y.Type().IsSlice() {
694 base.Errorf("arguments to copy must be slices; have %L, %L", n.X.Type(), n.Y.Type())
695 } else if !n.X.Type().IsSlice() {
696 base.Errorf("first argument to copy should be slice; have %L", n.X.Type())
697 } else {
698 base.Errorf("second argument to copy should be slice or string; have %L", n.Y.Type())
699 }
700 n.SetType(nil)
701 return n
702 }
703
704 if !types.Identical(n.X.Type().Elem(), n.Y.Type().Elem()) {
705 base.Errorf("arguments to copy have different element types: %L and %L", n.X.Type(), n.Y.Type())
706 n.SetType(nil)
707 return n
708 }
709 return n
710 }
711
712
713 func tcDelete(n *ir.CallExpr) ir.Node {
714 typecheckargs(n)
715 args := n.Args
716 if len(args) == 0 {
717 base.Errorf("missing arguments to delete")
718 n.SetType(nil)
719 return n
720 }
721
722 if len(args) == 1 {
723 base.Errorf("missing second (key) argument to delete")
724 n.SetType(nil)
725 return n
726 }
727
728 if len(args) != 2 {
729 base.Errorf("too many arguments to delete")
730 n.SetType(nil)
731 return n
732 }
733
734 l := args[0]
735 r := args[1]
736 if l.Type() != nil && !l.Type().IsMap() {
737 base.Errorf("first argument to delete must be map; have %L", l.Type())
738 n.SetType(nil)
739 return n
740 }
741
742 args[1] = AssignConv(r, l.Type().Key(), "delete")
743 return n
744 }
745
746
747 func tcMake(n *ir.CallExpr) ir.Node {
748 args := n.Args
749 if len(args) == 0 {
750 base.Errorf("missing argument to make")
751 n.SetType(nil)
752 return n
753 }
754
755 n.Args = nil
756 l := args[0]
757 l = typecheck(l, ctxType)
758 t := l.Type()
759 if t == nil {
760 n.SetType(nil)
761 return n
762 }
763
764 i := 1
765 var nn ir.Node
766 switch t.Kind() {
767 default:
768 base.Errorf("cannot make type %v", t)
769 n.SetType(nil)
770 return n
771
772 case types.TSLICE:
773 if i >= len(args) {
774 base.Errorf("missing len argument to make(%v)", t)
775 n.SetType(nil)
776 return n
777 }
778
779 l = args[i]
780 i++
781 l = Expr(l)
782 var r ir.Node
783 if i < len(args) {
784 r = args[i]
785 i++
786 r = Expr(r)
787 }
788
789 if l.Type() == nil || (r != nil && r.Type() == nil) {
790 n.SetType(nil)
791 return n
792 }
793 if !checkmake(t, "len", &l) || r != nil && !checkmake(t, "cap", &r) {
794 n.SetType(nil)
795 return n
796 }
797 if ir.IsConst(l, constant.Int) && r != nil && ir.IsConst(r, constant.Int) && constant.Compare(l.Val(), token.GTR, r.Val()) {
798 base.Errorf("len larger than cap in make(%v)", t)
799 n.SetType(nil)
800 return n
801 }
802 nn = ir.NewMakeExpr(n.Pos(), ir.OMAKESLICE, l, r)
803
804 case types.TMAP:
805 if i < len(args) {
806 l = args[i]
807 i++
808 l = Expr(l)
809 l = DefaultLit(l, types.Types[types.TINT])
810 if l.Type() == nil {
811 n.SetType(nil)
812 return n
813 }
814 if !checkmake(t, "size", &l) {
815 n.SetType(nil)
816 return n
817 }
818 } else {
819 l = ir.NewInt(0)
820 }
821 nn = ir.NewMakeExpr(n.Pos(), ir.OMAKEMAP, l, nil)
822 nn.SetEsc(n.Esc())
823
824 case types.TCHAN:
825 l = nil
826 if i < len(args) {
827 l = args[i]
828 i++
829 l = Expr(l)
830 l = DefaultLit(l, types.Types[types.TINT])
831 if l.Type() == nil {
832 n.SetType(nil)
833 return n
834 }
835 if !checkmake(t, "buffer", &l) {
836 n.SetType(nil)
837 return n
838 }
839 } else {
840 l = ir.NewInt(0)
841 }
842 nn = ir.NewMakeExpr(n.Pos(), ir.OMAKECHAN, l, nil)
843 }
844
845 if i < len(args) {
846 base.Errorf("too many arguments to make(%v)", t)
847 n.SetType(nil)
848 return n
849 }
850
851 nn.SetType(t)
852 return nn
853 }
854
855
856 func tcMakeSliceCopy(n *ir.MakeExpr) ir.Node {
857
858
859
860
861 t := n.Type()
862
863 if t == nil {
864 base.Fatalf("no type specified for OMAKESLICECOPY")
865 }
866
867 if !t.IsSlice() {
868 base.Fatalf("invalid type %v for OMAKESLICECOPY", n.Type())
869 }
870
871 if n.Len == nil {
872 base.Fatalf("missing len argument for OMAKESLICECOPY")
873 }
874
875 if n.Cap == nil {
876 base.Fatalf("missing slice argument to copy for OMAKESLICECOPY")
877 }
878
879 n.Len = Expr(n.Len)
880 n.Cap = Expr(n.Cap)
881
882 n.Len = DefaultLit(n.Len, types.Types[types.TINT])
883
884 if !n.Len.Type().IsInteger() && n.Type().Kind() != types.TIDEAL {
885 base.Errorf("non-integer len argument in OMAKESLICECOPY")
886 }
887
888 if ir.IsConst(n.Len, constant.Int) {
889 if ir.ConstOverflow(n.Len.Val(), types.Types[types.TINT]) {
890 base.Fatalf("len for OMAKESLICECOPY too large")
891 }
892 if constant.Sign(n.Len.Val()) < 0 {
893 base.Fatalf("len for OMAKESLICECOPY must be non-negative")
894 }
895 }
896 return n
897 }
898
899
900 func tcNew(n *ir.UnaryExpr) ir.Node {
901 if n.X == nil {
902
903
904 base.Fatalf("missing argument to new")
905 }
906 l := n.X
907 l = typecheck(l, ctxType)
908 t := l.Type()
909 if t == nil {
910 n.SetType(nil)
911 return n
912 }
913 n.X = l
914 n.SetType(types.NewPtr(t))
915 return n
916 }
917
918
919 func tcPanic(n *ir.UnaryExpr) ir.Node {
920 n.X = Expr(n.X)
921 n.X = AssignConv(n.X, types.Types[types.TINTER], "argument to panic")
922 if n.X.Type() == nil {
923 n.SetType(nil)
924 return n
925 }
926 return n
927 }
928
929
930 func tcPrint(n *ir.CallExpr) ir.Node {
931 typecheckargs(n)
932 ls := n.Args
933 for i1, n1 := range ls {
934
935 if ir.IsConst(n1, constant.Int) {
936 ls[i1] = DefaultLit(ls[i1], types.Types[types.TINT64])
937 } else {
938 ls[i1] = DefaultLit(ls[i1], nil)
939 }
940 }
941 return n
942 }
943
944
945 func tcRealImag(n *ir.UnaryExpr) ir.Node {
946 n.X = Expr(n.X)
947 l := n.X
948 t := l.Type()
949 if t == nil {
950 n.SetType(nil)
951 return n
952 }
953
954
955 switch t.Kind() {
956 case types.TIDEAL:
957 n.SetType(types.UntypedFloat)
958 case types.TCOMPLEX64:
959 n.SetType(types.Types[types.TFLOAT32])
960 case types.TCOMPLEX128:
961 n.SetType(types.Types[types.TFLOAT64])
962 default:
963 base.Errorf("invalid argument %L for %v", l, n.Op())
964 n.SetType(nil)
965 return n
966 }
967 return n
968 }
969
970
971 func tcRecover(n *ir.CallExpr) ir.Node {
972 if len(n.Args) != 0 {
973 base.Errorf("too many arguments to recover")
974 n.SetType(nil)
975 return n
976 }
977
978 n.SetType(types.Types[types.TINTER])
979 return n
980 }
981
982
983 func tcUnsafeAdd(n *ir.BinaryExpr) *ir.BinaryExpr {
984 if !types.AllowsGoVersion(curpkg(), 1, 17) {
985 base.ErrorfVers("go1.17", "unsafe.Add")
986 n.SetType(nil)
987 return n
988 }
989
990 n.X = AssignConv(Expr(n.X), types.Types[types.TUNSAFEPTR], "argument to unsafe.Add")
991 n.Y = DefaultLit(Expr(n.Y), types.Types[types.TINT])
992 if n.X.Type() == nil || n.Y.Type() == nil {
993 n.SetType(nil)
994 return n
995 }
996 if !n.Y.Type().IsInteger() {
997 n.SetType(nil)
998 return n
999 }
1000 n.SetType(n.X.Type())
1001 return n
1002 }
1003
1004
1005 func tcUnsafeSlice(n *ir.BinaryExpr) *ir.BinaryExpr {
1006 if !types.AllowsGoVersion(curpkg(), 1, 17) {
1007 base.ErrorfVers("go1.17", "unsafe.Slice")
1008 n.SetType(nil)
1009 return n
1010 }
1011
1012 n.X = Expr(n.X)
1013 n.Y = Expr(n.Y)
1014 if n.X.Type() == nil || n.Y.Type() == nil {
1015 n.SetType(nil)
1016 return n
1017 }
1018 t := n.X.Type()
1019 if !t.IsPtr() {
1020 base.Errorf("first argument to unsafe.Slice must be pointer; have %L", t)
1021 } else if t.Elem().NotInHeap() {
1022
1023
1024
1025
1026 base.Errorf("unsafe.Slice of incomplete (or unallocatable) type not allowed")
1027 }
1028
1029 if !checkunsafeslice(&n.Y) {
1030 n.SetType(nil)
1031 return n
1032 }
1033 n.SetType(types.NewSlice(t.Elem()))
1034 return n
1035 }
1036
View as plain text