1
2
3
4
5
6
7 package types2
8
9 import (
10 "cmd/compile/internal/syntax"
11 "go/constant"
12 "go/token"
13 )
14
15
16
17
18
19
20 func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (_ bool) {
21
22 bin := predeclaredFuncs[id]
23 if call.HasDots && id != _Append {
24
25 check.errorf(call, invalidOp+"invalid use of ... with built-in %s", bin.name)
26 check.use(call.ArgList...)
27 return
28 }
29
30
31
32
33
34
35 if id == _Len || id == _Cap {
36 defer func(b bool) {
37 check.hasCallOrRecv = b
38 }(check.hasCallOrRecv)
39 check.hasCallOrRecv = false
40 }
41
42
43 var arg func(*operand, int)
44 nargs := len(call.ArgList)
45 switch id {
46 default:
47
48 xlist, _ := check.exprList(call.ArgList, false)
49 arg = func(x *operand, i int) { *x = *xlist[i] }
50 nargs = len(xlist)
51
52 if nargs > 0 {
53 arg(x, 0)
54 if x.mode == invalid {
55 return
56 }
57 }
58 case _Make, _New, _Offsetof, _Trace:
59
60 }
61
62
63 {
64 msg := ""
65 if nargs < bin.nargs {
66 msg = "not enough"
67 } else if !bin.variadic && nargs > bin.nargs {
68 msg = "too many"
69 }
70 if msg != "" {
71 check.errorf(call, invalidOp+"%s arguments for %v (expected %d, found %d)", msg, call, bin.nargs, nargs)
72 return
73 }
74 }
75
76 switch id {
77 case _Append:
78
79
80
81
82
83 S := x.typ
84 var T Type
85 if s, _ := coreType(S).(*Slice); s != nil {
86 T = s.elem
87 } else {
88 var cause string
89 switch {
90 case x.isNil():
91 cause = "have untyped nil"
92 case isTypeParam(S):
93 if u := coreType(S); u != nil {
94 cause = check.sprintf("%s has core type %s", x, u)
95 } else {
96 cause = check.sprintf("%s has no core type", x)
97 }
98 default:
99 cause = check.sprintf("have %s", x)
100 }
101
102 check.errorf(x, "first argument to append must be a slice; %s", cause)
103 return
104 }
105
106
107 alist := []operand{*x}
108
109
110
111
112 if nargs == 2 && call.HasDots {
113 if ok, _ := x.assignableTo(check, NewSlice(universeByte), nil); ok {
114 arg(x, 1)
115 if x.mode == invalid {
116 return
117 }
118 if t := coreString(x.typ); t != nil && isString(t) {
119 if check.Types != nil {
120 sig := makeSig(S, S, x.typ)
121 sig.variadic = true
122 check.recordBuiltinType(call.Fun, sig)
123 }
124 x.mode = value
125 x.typ = S
126 break
127 }
128 alist = append(alist, *x)
129
130 }
131 }
132
133
134 sig := makeSig(S, S, NewSlice(T))
135 sig.variadic = true
136 var xlist []*operand
137
138 for i := range alist {
139 xlist = append(xlist, &alist[i])
140 }
141 for i := len(alist); i < nargs; i++ {
142 var x operand
143 arg(&x, i)
144 xlist = append(xlist, &x)
145 }
146 check.arguments(call, sig, nil, xlist, nil)
147
148
149 x.mode = value
150 x.typ = S
151 if check.Types != nil {
152 check.recordBuiltinType(call.Fun, sig)
153 }
154
155 case _Cap, _Len:
156
157
158 mode := invalid
159 var val constant.Value
160 switch t := arrayPtrDeref(under(x.typ)).(type) {
161 case *Basic:
162 if isString(t) && id == _Len {
163 if x.mode == constant_ {
164 mode = constant_
165 val = constant.MakeInt64(int64(len(constant.StringVal(x.val))))
166 } else {
167 mode = value
168 }
169 }
170
171 case *Array:
172 mode = value
173
174
175
176
177 if !check.hasCallOrRecv {
178 mode = constant_
179 if t.len >= 0 {
180 val = constant.MakeInt64(t.len)
181 } else {
182 val = constant.MakeUnknown()
183 }
184 }
185
186 case *Slice, *Chan:
187 mode = value
188
189 case *Map:
190 if id == _Len {
191 mode = value
192 }
193
194 case *Interface:
195 if !isTypeParam(x.typ) {
196 break
197 }
198 if t.typeSet().underIs(func(t Type) bool {
199 switch t := arrayPtrDeref(t).(type) {
200 case *Basic:
201 if isString(t) && id == _Len {
202 return true
203 }
204 case *Array, *Slice, *Chan:
205 return true
206 case *Map:
207 if id == _Len {
208 return true
209 }
210 }
211 return false
212 }) {
213 mode = value
214 }
215 }
216
217 if mode == invalid && under(x.typ) != Typ[Invalid] {
218 check.errorf(x, invalidArg+"%s for %s", x, bin.name)
219 return
220 }
221
222
223 if check.Types != nil && mode != constant_ {
224 check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ))
225 }
226
227 x.mode = mode
228 x.typ = Typ[Int]
229 x.val = val
230
231 case _Close:
232
233 if !underIs(x.typ, func(u Type) bool {
234 uch, _ := u.(*Chan)
235 if uch == nil {
236 check.errorf(x, invalidOp+"cannot close non-channel %s", x)
237 return false
238 }
239 if uch.dir == RecvOnly {
240 check.errorf(x, invalidOp+"cannot close receive-only channel %s", x)
241 return false
242 }
243 return true
244 }) {
245 return
246 }
247 x.mode = novalue
248 if check.Types != nil {
249 check.recordBuiltinType(call.Fun, makeSig(nil, x.typ))
250 }
251
252 case _Complex:
253
254 var y operand
255 arg(&y, 1)
256 if y.mode == invalid {
257 return
258 }
259
260
261 d := 0
262 if isUntyped(x.typ) {
263 d |= 1
264 }
265 if isUntyped(y.typ) {
266 d |= 2
267 }
268 switch d {
269 case 0:
270
271 case 1:
272
273 check.convertUntyped(x, y.typ)
274 case 2:
275
276 check.convertUntyped(&y, x.typ)
277 case 3:
278
279
280
281
282
283
284
285
286 if x.mode == constant_ && y.mode == constant_ {
287 toFloat := func(x *operand) {
288 if isNumeric(x.typ) && constant.Sign(constant.Imag(x.val)) == 0 {
289 x.typ = Typ[UntypedFloat]
290 }
291 }
292 toFloat(x)
293 toFloat(&y)
294 } else {
295 check.convertUntyped(x, Typ[Float64])
296 check.convertUntyped(&y, Typ[Float64])
297
298
299 }
300 }
301 if x.mode == invalid || y.mode == invalid {
302 return
303 }
304
305
306 if !Identical(x.typ, y.typ) {
307 check.errorf(x, invalidOp+"%v (mismatched types %s and %s)", call, x.typ, y.typ)
308 return
309 }
310
311
312
313 f := func(typ Type) Type {
314 assert(!isTypeParam(typ))
315 if t, _ := under(typ).(*Basic); t != nil {
316 switch t.kind {
317 case Float32:
318 return Typ[Complex64]
319 case Float64:
320 return Typ[Complex128]
321 case UntypedFloat:
322 return Typ[UntypedComplex]
323 }
324 }
325 return nil
326 }
327 resTyp := check.applyTypeFunc(f, x, id)
328 if resTyp == nil {
329 check.errorf(x, invalidArg+"arguments have type %s, expected floating-point", x.typ)
330 return
331 }
332
333
334 if x.mode == constant_ && y.mode == constant_ {
335 x.val = constant.BinaryOp(constant.ToFloat(x.val), token.ADD, constant.MakeImag(constant.ToFloat(y.val)))
336 } else {
337 x.mode = value
338 }
339
340 if check.Types != nil && x.mode != constant_ {
341 check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ, x.typ))
342 }
343
344 x.typ = resTyp
345
346 case _Copy:
347
348 dst, _ := coreType(x.typ).(*Slice)
349
350 var y operand
351 arg(&y, 1)
352 if y.mode == invalid {
353 return
354 }
355 src0 := coreString(y.typ)
356 if src0 != nil && isString(src0) {
357 src0 = NewSlice(universeByte)
358 }
359 src, _ := src0.(*Slice)
360
361 if dst == nil || src == nil {
362 check.errorf(x, invalidArg+"copy expects slice arguments; found %s and %s", x, &y)
363 return
364 }
365
366 if !Identical(dst.elem, src.elem) {
367 check.errorf(x, invalidArg+"arguments to copy %s and %s have different element types %s and %s", x, &y, dst.elem, src.elem)
368 return
369 }
370
371 if check.Types != nil {
372 check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ, y.typ))
373 }
374 x.mode = value
375 x.typ = Typ[Int]
376
377 case _Delete:
378
379
380
381 map_ := x.typ
382 var key Type
383 if !underIs(map_, func(u Type) bool {
384 map_, _ := u.(*Map)
385 if map_ == nil {
386 check.errorf(x, invalidArg+"%s is not a map", x)
387 return false
388 }
389 if key != nil && !Identical(map_.key, key) {
390 check.errorf(x, invalidArg+"maps of %s must have identical key types", x)
391 return false
392 }
393 key = map_.key
394 return true
395 }) {
396 return
397 }
398
399 arg(x, 1)
400 if x.mode == invalid {
401 return
402 }
403
404 check.assignment(x, key, "argument to delete")
405 if x.mode == invalid {
406 return
407 }
408
409 x.mode = novalue
410 if check.Types != nil {
411 check.recordBuiltinType(call.Fun, makeSig(nil, map_, key))
412 }
413
414 case _Imag, _Real:
415
416
417
418
419 if isUntyped(x.typ) {
420 if x.mode == constant_ {
421
422
423 if isNumeric(x.typ) {
424 x.typ = Typ[UntypedComplex]
425 }
426 } else {
427
428
429
430
431 check.convertUntyped(x, Typ[Complex128])
432
433 if x.mode == invalid {
434 return
435 }
436 }
437 }
438
439
440
441 f := func(typ Type) Type {
442 assert(!isTypeParam(typ))
443 if t, _ := under(typ).(*Basic); t != nil {
444 switch t.kind {
445 case Complex64:
446 return Typ[Float32]
447 case Complex128:
448 return Typ[Float64]
449 case UntypedComplex:
450 return Typ[UntypedFloat]
451 }
452 }
453 return nil
454 }
455 resTyp := check.applyTypeFunc(f, x, id)
456 if resTyp == nil {
457 check.errorf(x, invalidArg+"argument has type %s, expected complex type", x.typ)
458 return
459 }
460
461
462 if x.mode == constant_ {
463 if id == _Real {
464 x.val = constant.Real(x.val)
465 } else {
466 x.val = constant.Imag(x.val)
467 }
468 } else {
469 x.mode = value
470 }
471
472 if check.Types != nil && x.mode != constant_ {
473 check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ))
474 }
475
476 x.typ = resTyp
477
478 case _Make:
479
480
481
482 arg0 := call.ArgList[0]
483 T := check.varType(arg0)
484 if T == Typ[Invalid] {
485 return
486 }
487
488 var min int
489 switch coreType(T).(type) {
490 case *Slice:
491 min = 2
492 case *Map, *Chan:
493 min = 1
494 case nil:
495 check.errorf(arg0, invalidArg+"cannot make %s: no core type", arg0)
496 return
497 default:
498 check.errorf(arg0, invalidArg+"cannot make %s; type must be slice, map, or channel", arg0)
499 return
500 }
501 if nargs < min || min+1 < nargs {
502 check.errorf(call, invalidOp+"%v expects %d or %d arguments; found %d", call, min, min+1, nargs)
503 return
504 }
505
506 types := []Type{T}
507 var sizes []int64
508 for _, arg := range call.ArgList[1:] {
509 typ, size := check.index(arg, -1)
510 types = append(types, typ)
511 if size >= 0 {
512 sizes = append(sizes, size)
513 }
514 }
515 if len(sizes) == 2 && sizes[0] > sizes[1] {
516 check.error(call.ArgList[1], invalidArg+"length and capacity swapped")
517
518 }
519 x.mode = value
520 x.typ = T
521 if check.Types != nil {
522 check.recordBuiltinType(call.Fun, makeSig(x.typ, types...))
523 }
524
525 case _New:
526
527
528 T := check.varType(call.ArgList[0])
529 if T == Typ[Invalid] {
530 return
531 }
532
533 x.mode = value
534 x.typ = &Pointer{base: T}
535 if check.Types != nil {
536 check.recordBuiltinType(call.Fun, makeSig(x.typ, T))
537 }
538
539 case _Panic:
540
541
542
543 if check.sig != nil && check.sig.results.Len() > 0 {
544
545 p := check.isPanic
546 if p == nil {
547
548 p = make(map[*syntax.CallExpr]bool)
549 check.isPanic = p
550 }
551 p[call] = true
552 }
553
554 check.assignment(x, &emptyInterface, "argument to panic")
555 if x.mode == invalid {
556 return
557 }
558
559 x.mode = novalue
560 if check.Types != nil {
561 check.recordBuiltinType(call.Fun, makeSig(nil, &emptyInterface))
562 }
563
564 case _Print, _Println:
565
566
567 var params []Type
568 if nargs > 0 {
569 params = make([]Type, nargs)
570 for i := 0; i < nargs; i++ {
571 if i > 0 {
572 arg(x, i)
573 }
574 check.assignment(x, nil, "argument to "+predeclaredFuncs[id].name)
575 if x.mode == invalid {
576
577 return
578 }
579 params[i] = x.typ
580 }
581 }
582
583 x.mode = novalue
584 if check.Types != nil {
585 check.recordBuiltinType(call.Fun, makeSig(nil, params...))
586 }
587
588 case _Recover:
589
590 x.mode = value
591 x.typ = &emptyInterface
592 if check.Types != nil {
593 check.recordBuiltinType(call.Fun, makeSig(x.typ))
594 }
595
596 case _Add:
597
598 if !check.allowVersion(check.pkg, 1, 17) {
599 check.versionErrorf(call.Fun, "go1.17", "unsafe.Add")
600 return
601 }
602
603 check.assignment(x, Typ[UnsafePointer], "argument to unsafe.Add")
604 if x.mode == invalid {
605 return
606 }
607
608 var y operand
609 arg(&y, 1)
610 if !check.isValidIndex(&y, "length", true) {
611 return
612 }
613
614 x.mode = value
615 x.typ = Typ[UnsafePointer]
616 if check.Types != nil {
617 check.recordBuiltinType(call.Fun, makeSig(x.typ, x.typ, y.typ))
618 }
619
620 case _Alignof:
621
622 check.assignment(x, nil, "argument to unsafe.Alignof")
623 if x.mode == invalid {
624 return
625 }
626
627 if hasVarSize(x.typ) {
628 x.mode = value
629 if check.Types != nil {
630 check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ))
631 }
632 } else {
633 x.mode = constant_
634 x.val = constant.MakeInt64(check.conf.alignof(x.typ))
635
636 }
637 x.typ = Typ[Uintptr]
638
639 case _Offsetof:
640
641
642 arg0 := call.ArgList[0]
643 selx, _ := unparen(arg0).(*syntax.SelectorExpr)
644 if selx == nil {
645 check.errorf(arg0, invalidArg+"%s is not a selector expression", arg0)
646 check.use(arg0)
647 return
648 }
649
650 check.expr(x, selx.X)
651 if x.mode == invalid {
652 return
653 }
654
655 base := derefStructPtr(x.typ)
656 sel := selx.Sel.Value
657 obj, index, indirect := LookupFieldOrMethod(base, false, check.pkg, sel)
658 switch obj.(type) {
659 case nil:
660 check.errorf(x, invalidArg+"%s has no single field %s", base, sel)
661 return
662 case *Func:
663
664
665
666
667 check.errorf(arg0, invalidArg+"%s is a method value", arg0)
668 return
669 }
670 if indirect {
671 check.errorf(x, invalidArg+"field %s is embedded via a pointer in %s", sel, base)
672 return
673 }
674
675
676 check.recordSelection(selx, FieldVal, base, obj, index, false)
677
678
679 {
680 mode := value
681 if x.mode == variable || indirect {
682 mode = variable
683 }
684 check.record(&operand{mode, selx, obj.Type(), nil, 0})
685 }
686
687
688
689
690
691 if hasVarSize(base) {
692 x.mode = value
693 if check.Types != nil {
694 check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], obj.Type()))
695 }
696 } else {
697 x.mode = constant_
698 x.val = constant.MakeInt64(check.conf.offsetof(base, index))
699
700 }
701 x.typ = Typ[Uintptr]
702
703 case _Sizeof:
704
705 check.assignment(x, nil, "argument to unsafe.Sizeof")
706 if x.mode == invalid {
707 return
708 }
709
710 if hasVarSize(x.typ) {
711 x.mode = value
712 if check.Types != nil {
713 check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ))
714 }
715 } else {
716 x.mode = constant_
717 x.val = constant.MakeInt64(check.conf.sizeof(x.typ))
718
719 }
720 x.typ = Typ[Uintptr]
721
722 case _Slice:
723
724 if !check.allowVersion(check.pkg, 1, 17) {
725 check.versionErrorf(call.Fun, "go1.17", "unsafe.Slice")
726 return
727 }
728
729 typ, _ := under(x.typ).(*Pointer)
730 if typ == nil {
731 check.errorf(x, invalidArg+"%s is not a pointer", x)
732 return
733 }
734
735 var y operand
736 arg(&y, 1)
737 if !check.isValidIndex(&y, "length", false) {
738 return
739 }
740
741 x.mode = value
742 x.typ = NewSlice(typ.base)
743 if check.Types != nil {
744 check.recordBuiltinType(call.Fun, makeSig(x.typ, typ, y.typ))
745 }
746
747 case _Assert:
748
749
750
751 if x.mode != constant_ || !isBoolean(x.typ) {
752 check.errorf(x, invalidArg+"%s is not a boolean constant", x)
753 return
754 }
755 if x.val.Kind() != constant.Bool {
756 check.errorf(x, "internal error: value of %s should be a boolean constant", x)
757 return
758 }
759 if !constant.BoolVal(x.val) {
760 check.errorf(call, "%v failed", call)
761
762 }
763
764
765 case _Trace:
766
767
768
769
770
771 if nargs == 0 {
772 check.dump("%v: trace() without arguments", posFor(call))
773 x.mode = novalue
774 break
775 }
776 var t operand
777 x1 := x
778 for _, arg := range call.ArgList {
779 check.rawExpr(x1, arg, nil, false)
780 check.dump("%v: %s", posFor(x1), x1)
781 x1 = &t
782 }
783
784
785 default:
786 unreachable()
787 }
788
789 return true
790 }
791
792
793 func hasVarSize(t Type) bool {
794 switch u := under(t).(type) {
795 case *Array:
796 return hasVarSize(u.elem)
797 case *Struct:
798 for _, f := range u.fields {
799 if hasVarSize(f.typ) {
800 return true
801 }
802 }
803 case *Interface:
804 return isTypeParam(t)
805 case *Named, *Union:
806 unreachable()
807 }
808 return false
809 }
810
811
812
813
814
815
816
817
818 func (check *Checker) applyTypeFunc(f func(Type) Type, x *operand, id builtinId) Type {
819 if tp, _ := x.typ.(*TypeParam); tp != nil {
820
821
822 var terms []*Term
823 if !tp.is(func(t *term) bool {
824 if t == nil {
825 return false
826 }
827 if r := f(t.typ); r != nil {
828 terms = append(terms, NewTerm(t.tilde, r))
829 return true
830 }
831 return false
832 }) {
833 return nil
834 }
835
836
837
838
839
840 check.softErrorf(x, "%s not supported as argument to %s for go1.18 (see issue #50937)", x, predeclaredFuncs[id].name)
841
842
843
844
845 tpar := NewTypeName(nopos, check.pkg, tp.obj.name, nil)
846 ptyp := check.newTypeParam(tpar, NewInterfaceType(nil, []Type{NewUnion(terms)}))
847 ptyp.index = tp.index
848
849 return ptyp
850 }
851
852 return f(x.typ)
853 }
854
855
856
857 func makeSig(res Type, args ...Type) *Signature {
858 list := make([]*Var, len(args))
859 for i, param := range args {
860 list[i] = NewVar(nopos, nil, "", Default(param))
861 }
862 params := NewTuple(list...)
863 var result *Tuple
864 if res != nil {
865 assert(!isUntyped(res))
866 result = NewTuple(NewVar(nopos, nil, "", res))
867 }
868 return &Signature{params: params, results: result}
869 }
870
871
872
873 func arrayPtrDeref(typ Type) Type {
874 if p, ok := typ.(*Pointer); ok {
875 if a, _ := under(p.base).(*Array); a != nil {
876 return a
877 }
878 }
879 return typ
880 }
881
882
883 func unparen(e syntax.Expr) syntax.Expr {
884 for {
885 p, ok := e.(*syntax.ParenExpr)
886 if !ok {
887 return e
888 }
889 e = p.X
890 }
891 }
892
View as plain text