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