1
2
3
4
5 package typecheck
6
7 import (
8 "fmt"
9 "go/constant"
10 "go/token"
11 "internal/types/errors"
12 "strings"
13
14 "cmd/compile/internal/base"
15 "cmd/compile/internal/ir"
16 "cmd/compile/internal/types"
17 "cmd/internal/src"
18 )
19
20 func tcShift(n, l, r ir.Node) (ir.Node, ir.Node, *types.Type) {
21 if l.Type() == nil || r.Type() == nil {
22 return l, r, nil
23 }
24
25 r = DefaultLit(r, types.Types[types.TUINT])
26 t := r.Type()
27 if !t.IsInteger() {
28 base.Errorf("invalid operation: %v (shift count type %v, must be integer)", n, r.Type())
29 return l, r, nil
30 }
31 t = l.Type()
32 if t != nil && t.Kind() != types.TIDEAL && !t.IsInteger() {
33 base.Errorf("invalid operation: %v (shift of type %v)", n, t)
34 return l, r, nil
35 }
36
37
38
39 t = l.Type()
40 if (l.Type() == types.UntypedFloat || l.Type() == types.UntypedComplex) && r.Op() == ir.OLITERAL {
41 t = types.UntypedInt
42 }
43 return l, r, t
44 }
45
46
47
48
49
50
51
52 func tcArith(n ir.Node, op ir.Op, l, r ir.Node) (ir.Node, ir.Node, *types.Type) {
53 l, r = defaultlit2(l, r, false)
54 if l.Type() == nil || r.Type() == nil {
55 return l, r, nil
56 }
57 t := l.Type()
58 if t.Kind() == types.TIDEAL {
59 t = r.Type()
60 }
61 aop := ir.OXXX
62 if n.Op().IsCmp() && t.Kind() != types.TIDEAL && !types.Identical(l.Type(), r.Type()) {
63
64
65
66
67
68
69
70 converted := false
71 if r.Type().Kind() != types.TBLANK {
72 aop, _ = assignOp(l.Type(), r.Type())
73 if aop != ir.OXXX {
74 if r.Type().IsInterface() && !l.Type().IsInterface() && !types.IsComparable(l.Type()) {
75 base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(l.Type()))
76 return l, r, nil
77 }
78
79 types.CalcSize(l.Type())
80 if r.Type().IsInterface() == l.Type().IsInterface() || l.Type().Size() >= 1<<16 {
81 l = ir.NewConvExpr(base.Pos, aop, r.Type(), l)
82 l.SetTypecheck(1)
83 }
84
85 t = r.Type()
86 converted = true
87 }
88 }
89
90 if !converted && l.Type().Kind() != types.TBLANK {
91 aop, _ = assignOp(r.Type(), l.Type())
92 if aop != ir.OXXX {
93 if l.Type().IsInterface() && !r.Type().IsInterface() && !types.IsComparable(r.Type()) {
94 base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(r.Type()))
95 return l, r, nil
96 }
97
98 types.CalcSize(r.Type())
99 if r.Type().IsInterface() == l.Type().IsInterface() || r.Type().Size() >= 1<<16 {
100 r = ir.NewConvExpr(base.Pos, aop, l.Type(), r)
101 r.SetTypecheck(1)
102 }
103
104 t = l.Type()
105 }
106 }
107 }
108
109 if t.Kind() != types.TIDEAL && !types.Identical(l.Type(), r.Type()) {
110 l, r = defaultlit2(l, r, true)
111 if l.Type() == nil || r.Type() == nil {
112 return l, r, nil
113 }
114 if l.Type().IsInterface() == r.Type().IsInterface() || aop == 0 {
115 base.Errorf("invalid operation: %v (mismatched types %v and %v)", n, l.Type(), r.Type())
116 return l, r, nil
117 }
118 }
119
120 if t.Kind() == types.TIDEAL {
121 t = mixUntyped(l.Type(), r.Type())
122 }
123 if dt := defaultType(t); !okfor[op][dt.Kind()] {
124 base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(t))
125 return l, r, nil
126 }
127
128
129
130 if l.Type().IsArray() && !types.IsComparable(l.Type()) {
131 base.Errorf("invalid operation: %v (%v cannot be compared)", n, l.Type())
132 return l, r, nil
133 }
134
135 if l.Type().IsSlice() && !ir.IsNil(l) && !ir.IsNil(r) {
136 base.Errorf("invalid operation: %v (slice can only be compared to nil)", n)
137 return l, r, nil
138 }
139
140 if l.Type().IsMap() && !ir.IsNil(l) && !ir.IsNil(r) {
141 base.Errorf("invalid operation: %v (map can only be compared to nil)", n)
142 return l, r, nil
143 }
144
145 if l.Type().Kind() == types.TFUNC && !ir.IsNil(l) && !ir.IsNil(r) {
146 base.Errorf("invalid operation: %v (func can only be compared to nil)", n)
147 return l, r, nil
148 }
149
150 if l.Type().IsStruct() {
151 if f := types.IncomparableField(l.Type()); f != nil {
152 base.Errorf("invalid operation: %v (struct containing %v cannot be compared)", n, f.Type)
153 return l, r, nil
154 }
155 }
156
157 return l, r, t
158 }
159
160
161
162
163 func tcCompLit(n *ir.CompLitExpr) (res ir.Node) {
164 if base.EnableTrace && base.Flag.LowerT {
165 defer tracePrint("tcCompLit", n)(&res)
166 }
167
168 lno := base.Pos
169 defer func() {
170 base.Pos = lno
171 }()
172
173 ir.SetPos(n)
174
175 t := n.Type()
176 base.AssertfAt(t != nil, n.Pos(), "missing type in composite literal")
177
178 switch t.Kind() {
179 default:
180 base.Errorf("invalid composite literal type %v", t)
181 n.SetType(nil)
182
183 case types.TARRAY:
184 typecheckarraylit(t.Elem(), t.NumElem(), n.List, "array literal")
185 n.SetOp(ir.OARRAYLIT)
186
187 case types.TSLICE:
188 length := typecheckarraylit(t.Elem(), -1, n.List, "slice literal")
189 n.SetOp(ir.OSLICELIT)
190 n.Len = length
191
192 case types.TMAP:
193 for i3, l := range n.List {
194 ir.SetPos(l)
195 if l.Op() != ir.OKEY {
196 n.List[i3] = Expr(l)
197 base.Errorf("missing key in map literal")
198 continue
199 }
200 l := l.(*ir.KeyExpr)
201
202 r := l.Key
203 r = Expr(r)
204 l.Key = AssignConv(r, t.Key(), "map key")
205
206 r = l.Value
207 r = Expr(r)
208 l.Value = AssignConv(r, t.Elem(), "map value")
209 }
210
211 n.SetOp(ir.OMAPLIT)
212
213 case types.TSTRUCT:
214
215 types.CalcSize(t)
216
217 errored := false
218 if len(n.List) != 0 && nokeys(n.List) {
219
220 ls := n.List
221 for i, n1 := range ls {
222 ir.SetPos(n1)
223 n1 = Expr(n1)
224 ls[i] = n1
225 if i >= t.NumFields() {
226 if !errored {
227 base.Errorf("too many values in %v", n)
228 errored = true
229 }
230 continue
231 }
232
233 f := t.Field(i)
234 s := f.Sym
235
236
237
238
239
240
241
242
243
244 if !(ir.CurFunc != nil && strings.Contains(ir.CurFunc.Nname.Sym().Name, "[")) {
245 if s != nil && !types.IsExported(s.Name) && s.Pkg != types.LocalPkg {
246 base.Errorf("implicit assignment of unexported field '%s' in %v literal", s.Name, t)
247 }
248 }
249
250 n1 = AssignConv(n1, f.Type, "field value")
251 ls[i] = ir.NewStructKeyExpr(base.Pos, f, n1)
252 }
253 if len(ls) < t.NumFields() {
254 base.Errorf("too few values in %v", n)
255 }
256 } else {
257 hash := make(map[string]bool)
258
259
260 ls := n.List
261 for i, n := range ls {
262 ir.SetPos(n)
263
264 sk, ok := n.(*ir.StructKeyExpr)
265 if !ok {
266 kv, ok := n.(*ir.KeyExpr)
267 if !ok {
268 if !errored {
269 base.Errorf("mixture of field:value and value initializers")
270 errored = true
271 }
272 ls[i] = Expr(n)
273 continue
274 }
275
276 sk = tcStructLitKey(t, kv)
277 if sk == nil {
278 continue
279 }
280
281 fielddup(sk.Sym().Name, hash)
282 }
283
284
285 sk.Value = Expr(sk.Value)
286 sk.Value = AssignConv(sk.Value, sk.Field.Type, "field value")
287 ls[i] = sk
288 }
289 }
290
291 n.SetOp(ir.OSTRUCTLIT)
292 }
293
294 return n
295 }
296
297
298
299 func tcStructLitKey(typ *types.Type, kv *ir.KeyExpr) *ir.StructKeyExpr {
300 key := kv.Key
301
302 sym := key.Sym()
303
304
305
306
307
308 if sym == nil || sym.Pkg != types.LocalPkg || key.Op() == ir.OXDOT || sym.IsBlank() {
309 base.Errorf("invalid field name %v in struct initializer", key)
310 return nil
311 }
312
313 if f := Lookdot1(nil, sym, typ, typ.Fields(), 0); f != nil {
314 return ir.NewStructKeyExpr(kv.Pos(), f, kv.Value)
315 }
316
317 if ci := Lookdot1(nil, sym, typ, typ.Fields(), 2); ci != nil {
318 if visible(ci.Sym) {
319 base.Errorf("unknown field '%v' in struct literal of type %v (but does have %v)", sym, typ, ci.Sym)
320 } else if nonexported(sym) && sym.Name == ci.Sym.Name {
321 base.Errorf("cannot refer to unexported field '%v' in struct literal of type %v", sym, typ)
322 } else {
323 base.Errorf("unknown field '%v' in struct literal of type %v", sym, typ)
324 }
325 return nil
326 }
327
328 var f *types.Field
329 p, _ := dotpath(sym, typ, &f, true)
330 if p == nil || f.IsMethod() {
331 base.Errorf("unknown field '%v' in struct literal of type %v", sym, typ)
332 return nil
333 }
334
335
336 var ep []string
337 for ei := len(p) - 1; ei >= 0; ei-- {
338 ep = append(ep, p[ei].field.Sym.Name)
339 }
340 ep = append(ep, sym.Name)
341 base.Errorf("cannot use promoted field %v in struct literal of type %v", strings.Join(ep, "."), typ)
342 return nil
343 }
344
345
346 func tcConv(n *ir.ConvExpr) ir.Node {
347 types.CheckSize(n.Type())
348 n.X = Expr(n.X)
349 n.X = convlit1(n.X, n.Type(), true, nil)
350 t := n.X.Type()
351 if t == nil || n.Type() == nil {
352 n.SetType(nil)
353 return n
354 }
355 op, why := convertOp(n.X.Op() == ir.OLITERAL, t, n.Type())
356 if op == ir.OXXX {
357
358 base.ErrorfAt(n.Pos(), errors.InvalidConversion, "cannot convert %L to type %v%s", n.X, n.Type(), why)
359 n.SetType(nil)
360 return n
361 }
362
363 n.SetOp(op)
364 switch n.Op() {
365 case ir.OCONVNOP:
366 if t.Kind() == n.Type().Kind() {
367 switch t.Kind() {
368 case types.TFLOAT32, types.TFLOAT64, types.TCOMPLEX64, types.TCOMPLEX128:
369
370
371 n.SetOp(ir.OCONV)
372 }
373 }
374
375
376
377 case ir.OSTR2BYTES:
378
379
380 case ir.OSTR2RUNES:
381 if n.X.Op() == ir.OLITERAL {
382 return stringtoruneslit(n)
383 }
384
385 case ir.OBYTES2STR:
386 if t.Elem() != types.ByteType && t.Elem() != types.Types[types.TUINT8] {
387
388
389
390
391 n.X = ir.NewConvExpr(n.X.Pos(), ir.OCONVNOP, types.NewSlice(types.ByteType), n.X)
392 n.X.SetTypecheck(1)
393 }
394
395 case ir.ORUNES2STR:
396 if t.Elem() != types.RuneType && t.Elem() != types.Types[types.TINT32] {
397
398
399
400
401 n.X = ir.NewConvExpr(n.X.Pos(), ir.OCONVNOP, types.NewSlice(types.RuneType), n.X)
402 n.X.SetTypecheck(1)
403 }
404
405 }
406 return n
407 }
408
409
410
411
412 func DotField(pos src.XPos, x ir.Node, index int) *ir.SelectorExpr {
413 op, typ := ir.ODOT, x.Type()
414 if typ.IsPtr() {
415 op, typ = ir.ODOTPTR, typ.Elem()
416 }
417 if !typ.IsStruct() {
418 base.FatalfAt(pos, "DotField of non-struct: %L", x)
419 }
420
421
422 types.CalcSize(typ)
423
424 field := typ.Field(index)
425 return dot(pos, field.Type, op, x, field)
426 }
427
428 func dot(pos src.XPos, typ *types.Type, op ir.Op, x ir.Node, selection *types.Field) *ir.SelectorExpr {
429 n := ir.NewSelectorExpr(pos, op, x, selection.Sym)
430 n.Selection = selection
431 n.SetType(typ)
432 n.SetTypecheck(1)
433 return n
434 }
435
436
437
438
439 func XDotField(pos src.XPos, x ir.Node, sym *types.Sym) *ir.SelectorExpr {
440 n := Expr(ir.NewSelectorExpr(pos, ir.OXDOT, x, sym)).(*ir.SelectorExpr)
441 if n.Op() != ir.ODOT && n.Op() != ir.ODOTPTR {
442 base.FatalfAt(pos, "unexpected result op: %v (%v)", n.Op(), n)
443 }
444 return n
445 }
446
447
448
449
450
451
452
453 func XDotMethod(pos src.XPos, x ir.Node, sym *types.Sym, callee bool) *ir.SelectorExpr {
454 n := ir.NewSelectorExpr(pos, ir.OXDOT, x, sym)
455 if callee {
456 n = Callee(n).(*ir.SelectorExpr)
457 if n.Op() != ir.ODOTMETH && n.Op() != ir.ODOTINTER {
458 base.FatalfAt(pos, "unexpected result op: %v (%v)", n.Op(), n)
459 }
460 } else {
461 n = Expr(n).(*ir.SelectorExpr)
462 if n.Op() != ir.OMETHVALUE {
463 base.FatalfAt(pos, "unexpected result op: %v (%v)", n.Op(), n)
464 }
465 }
466 return n
467 }
468
469
470 func tcDot(n *ir.SelectorExpr, top int) ir.Node {
471 if n.Op() == ir.OXDOT {
472 n = AddImplicitDots(n)
473 n.SetOp(ir.ODOT)
474 if n.X == nil {
475 n.SetType(nil)
476 return n
477 }
478 }
479
480 n.X = Expr(n.X)
481 n.X = DefaultLit(n.X, nil)
482
483 t := n.X.Type()
484 if t == nil {
485 base.UpdateErrorDot(ir.Line(n), fmt.Sprint(n.X), fmt.Sprint(n))
486 n.SetType(nil)
487 return n
488 }
489
490 if n.X.Op() == ir.OTYPE {
491 base.FatalfAt(n.Pos(), "use NewMethodExpr to construct OMETHEXPR")
492 }
493
494 if t.IsPtr() && !t.Elem().IsInterface() {
495 t = t.Elem()
496 if t == nil {
497 n.SetType(nil)
498 return n
499 }
500 n.SetOp(ir.ODOTPTR)
501 types.CheckSize(t)
502 }
503
504 if n.Sel.IsBlank() {
505 base.Errorf("cannot refer to blank field or method")
506 n.SetType(nil)
507 return n
508 }
509
510 if Lookdot(n, t, 0) == nil {
511
512 switch {
513 case t.IsEmptyInterface():
514 base.Errorf("%v undefined (type %v is interface with no methods)", n, n.X.Type())
515
516 case t.IsPtr() && t.Elem().IsInterface():
517
518 base.Errorf("%v undefined (type %v is pointer to interface, not interface)", n, n.X.Type())
519
520 case Lookdot(n, t, 1) != nil:
521
522 base.Errorf("%v undefined (cannot refer to unexported field or method %v)", n, n.Sel)
523
524 default:
525 if mt := Lookdot(n, t, 2); mt != nil && visible(mt.Sym) {
526 base.Errorf("%v undefined (type %v has no field or method %v, but does have %v)", n, n.X.Type(), n.Sel, mt.Sym)
527 } else {
528 base.Errorf("%v undefined (type %v has no field or method %v)", n, n.X.Type(), n.Sel)
529 }
530 }
531 n.SetType(nil)
532 return n
533 }
534
535 if (n.Op() == ir.ODOTINTER || n.Op() == ir.ODOTMETH) && top&ctxCallee == 0 {
536 n.SetOp(ir.OMETHVALUE)
537 n.SetType(NewMethodType(n.Type(), nil))
538 }
539 return n
540 }
541
542
543 func tcDotType(n *ir.TypeAssertExpr) ir.Node {
544 n.X = Expr(n.X)
545 n.X = DefaultLit(n.X, nil)
546 l := n.X
547 t := l.Type()
548 if t == nil {
549 n.SetType(nil)
550 return n
551 }
552 if !t.IsInterface() {
553 base.Errorf("invalid type assertion: %v (non-interface type %v on left)", n, t)
554 n.SetType(nil)
555 return n
556 }
557
558 base.AssertfAt(n.Type() != nil, n.Pos(), "missing type: %v", n)
559
560 if n.Type() != nil && !n.Type().IsInterface() {
561 why := ImplementsExplain(n.Type(), t)
562 if why != "" {
563 base.Fatalf("impossible type assertion:\n\t%s", why)
564 n.SetType(nil)
565 return n
566 }
567 }
568 return n
569 }
570
571
572 func tcITab(n *ir.UnaryExpr) ir.Node {
573 n.X = Expr(n.X)
574 t := n.X.Type()
575 if t == nil {
576 n.SetType(nil)
577 return n
578 }
579 if !t.IsInterface() {
580 base.Fatalf("OITAB of %v", t)
581 }
582 n.SetType(types.NewPtr(types.Types[types.TUINTPTR]))
583 return n
584 }
585
586
587 func tcIndex(n *ir.IndexExpr) ir.Node {
588 n.X = Expr(n.X)
589 n.X = DefaultLit(n.X, nil)
590 n.X = implicitstar(n.X)
591 l := n.X
592 n.Index = Expr(n.Index)
593 r := n.Index
594 t := l.Type()
595 if t == nil || r.Type() == nil {
596 n.SetType(nil)
597 return n
598 }
599 switch t.Kind() {
600 default:
601 base.Errorf("invalid operation: %v (type %v does not support indexing)", n, t)
602 n.SetType(nil)
603 return n
604
605 case types.TSTRING, types.TARRAY, types.TSLICE:
606 n.Index = indexlit(n.Index)
607 if t.IsString() {
608 n.SetType(types.ByteType)
609 } else {
610 n.SetType(t.Elem())
611 }
612 why := "string"
613 if t.IsArray() {
614 why = "array"
615 } else if t.IsSlice() {
616 why = "slice"
617 }
618
619 if n.Index.Type() != nil && !n.Index.Type().IsInteger() {
620 base.Errorf("non-integer %s index %v", why, n.Index)
621 return n
622 }
623
624 case types.TMAP:
625 n.Index = AssignConv(n.Index, t.Key(), "map index")
626 n.SetType(t.Elem())
627 n.SetOp(ir.OINDEXMAP)
628 n.Assigned = false
629 }
630 return n
631 }
632
633
634 func tcLenCap(n *ir.UnaryExpr) ir.Node {
635 n.X = Expr(n.X)
636 n.X = DefaultLit(n.X, nil)
637 n.X = implicitstar(n.X)
638 l := n.X
639 t := l.Type()
640 if t == nil {
641 n.SetType(nil)
642 return n
643 }
644
645 var ok bool
646 if n.Op() == ir.OLEN {
647 ok = okforlen[t.Kind()]
648 } else {
649 ok = okforcap[t.Kind()]
650 }
651 if !ok {
652 base.Errorf("invalid argument %L for %v", l, n.Op())
653 n.SetType(nil)
654 return n
655 }
656
657 n.SetType(types.Types[types.TINT])
658 return n
659 }
660
661
662 func tcUnsafeData(n *ir.UnaryExpr) ir.Node {
663 n.X = Expr(n.X)
664 n.X = DefaultLit(n.X, nil)
665 l := n.X
666 t := l.Type()
667 if t == nil {
668 n.SetType(nil)
669 return n
670 }
671
672 var kind types.Kind
673 if n.Op() == ir.OUNSAFESLICEDATA {
674 kind = types.TSLICE
675 } else {
676
677 kind = types.TSTRING
678 }
679
680 if t.Kind() != kind {
681 base.Errorf("invalid argument %L for %v", l, n.Op())
682 n.SetType(nil)
683 return n
684 }
685
686 if kind == types.TSTRING {
687 t = types.ByteType
688 } else {
689 t = t.Elem()
690 }
691 n.SetType(types.NewPtr(t))
692 return n
693 }
694
695
696 func tcRecv(n *ir.UnaryExpr) ir.Node {
697 n.X = Expr(n.X)
698 n.X = DefaultLit(n.X, nil)
699 l := n.X
700 t := l.Type()
701 if t == nil {
702 n.SetType(nil)
703 return n
704 }
705 if !t.IsChan() {
706 base.Errorf("invalid operation: %v (receive from non-chan type %v)", n, t)
707 n.SetType(nil)
708 return n
709 }
710
711 if !t.ChanDir().CanRecv() {
712 base.Errorf("invalid operation: %v (receive from send-only type %v)", n, t)
713 n.SetType(nil)
714 return n
715 }
716
717 n.SetType(t.Elem())
718 return n
719 }
720
721
722 func tcSPtr(n *ir.UnaryExpr) ir.Node {
723 n.X = Expr(n.X)
724 t := n.X.Type()
725 if t == nil {
726 n.SetType(nil)
727 return n
728 }
729 if !t.IsSlice() && !t.IsString() {
730 base.Fatalf("OSPTR of %v", t)
731 }
732 if t.IsString() {
733 n.SetType(types.NewPtr(types.Types[types.TUINT8]))
734 } else {
735 n.SetType(types.NewPtr(t.Elem()))
736 }
737 return n
738 }
739
740
741 func tcSlice(n *ir.SliceExpr) ir.Node {
742 n.X = DefaultLit(Expr(n.X), nil)
743 n.Low = indexlit(Expr(n.Low))
744 n.High = indexlit(Expr(n.High))
745 n.Max = indexlit(Expr(n.Max))
746 hasmax := n.Op().IsSlice3()
747 l := n.X
748 if l.Type() == nil {
749 n.SetType(nil)
750 return n
751 }
752 if l.Type().IsArray() {
753 if !ir.IsAddressable(n.X) {
754 base.Errorf("invalid operation %v (slice of unaddressable value)", n)
755 n.SetType(nil)
756 return n
757 }
758
759 addr := NodAddr(n.X)
760 addr.SetImplicit(true)
761 n.X = Expr(addr)
762 l = n.X
763 }
764 t := l.Type()
765 var tp *types.Type
766 if t.IsString() {
767 if hasmax {
768 base.Errorf("invalid operation %v (3-index slice of string)", n)
769 n.SetType(nil)
770 return n
771 }
772 n.SetType(t)
773 n.SetOp(ir.OSLICESTR)
774 } else if t.IsPtr() && t.Elem().IsArray() {
775 tp = t.Elem()
776 n.SetType(types.NewSlice(tp.Elem()))
777 types.CalcSize(n.Type())
778 if hasmax {
779 n.SetOp(ir.OSLICE3ARR)
780 } else {
781 n.SetOp(ir.OSLICEARR)
782 }
783 } else if t.IsSlice() {
784 n.SetType(t)
785 } else {
786 base.Errorf("cannot slice %v (type %v)", l, t)
787 n.SetType(nil)
788 return n
789 }
790
791 if n.Low != nil && !checksliceindex(l, n.Low, tp) {
792 n.SetType(nil)
793 return n
794 }
795 if n.High != nil && !checksliceindex(l, n.High, tp) {
796 n.SetType(nil)
797 return n
798 }
799 if n.Max != nil && !checksliceindex(l, n.Max, tp) {
800 n.SetType(nil)
801 return n
802 }
803 if !checksliceconst(n.Low, n.High) || !checksliceconst(n.Low, n.Max) || !checksliceconst(n.High, n.Max) {
804 n.SetType(nil)
805 return n
806 }
807 return n
808 }
809
810
811 func tcSliceHeader(n *ir.SliceHeaderExpr) ir.Node {
812
813
814
815
816 t := n.Type()
817 if t == nil {
818 base.Fatalf("no type specified for OSLICEHEADER")
819 }
820
821 if !t.IsSlice() {
822 base.Fatalf("invalid type %v for OSLICEHEADER", n.Type())
823 }
824
825 if n.Ptr == nil || n.Ptr.Type() == nil || !n.Ptr.Type().IsUnsafePtr() {
826 base.Fatalf("need unsafe.Pointer for OSLICEHEADER")
827 }
828
829 n.Ptr = Expr(n.Ptr)
830 n.Len = DefaultLit(Expr(n.Len), types.Types[types.TINT])
831 n.Cap = DefaultLit(Expr(n.Cap), types.Types[types.TINT])
832
833 if ir.IsConst(n.Len, constant.Int) && ir.Int64Val(n.Len) < 0 {
834 base.Fatalf("len for OSLICEHEADER must be non-negative")
835 }
836
837 if ir.IsConst(n.Cap, constant.Int) && ir.Int64Val(n.Cap) < 0 {
838 base.Fatalf("cap for OSLICEHEADER must be non-negative")
839 }
840
841 if ir.IsConst(n.Len, constant.Int) && ir.IsConst(n.Cap, constant.Int) && constant.Compare(n.Len.Val(), token.GTR, n.Cap.Val()) {
842 base.Fatalf("len larger than cap for OSLICEHEADER")
843 }
844
845 return n
846 }
847
848
849 func tcStringHeader(n *ir.StringHeaderExpr) ir.Node {
850 t := n.Type()
851 if t == nil {
852 base.Fatalf("no type specified for OSTRINGHEADER")
853 }
854
855 if !t.IsString() {
856 base.Fatalf("invalid type %v for OSTRINGHEADER", n.Type())
857 }
858
859 if n.Ptr == nil || n.Ptr.Type() == nil || !n.Ptr.Type().IsUnsafePtr() {
860 base.Fatalf("need unsafe.Pointer for OSTRINGHEADER")
861 }
862
863 n.Ptr = Expr(n.Ptr)
864 n.Len = DefaultLit(Expr(n.Len), types.Types[types.TINT])
865
866 if ir.IsConst(n.Len, constant.Int) && ir.Int64Val(n.Len) < 0 {
867 base.Fatalf("len for OSTRINGHEADER must be non-negative")
868 }
869
870 return n
871 }
872
873
874 func tcStar(n *ir.StarExpr, top int) ir.Node {
875 n.X = typecheck(n.X, ctxExpr|ctxType)
876 l := n.X
877 t := l.Type()
878 if t == nil {
879 n.SetType(nil)
880 return n
881 }
882
883
884
885 if l.Op() == ir.OTYPE {
886 base.Fatalf("unexpected type in deref expression: %v", l)
887 }
888
889 if !t.IsPtr() {
890 if top&(ctxExpr|ctxStmt) != 0 {
891 base.Errorf("invalid indirect of %L", n.X)
892 n.SetType(nil)
893 return n
894 }
895 base.Errorf("%v is not a type", l)
896 return n
897 }
898
899 n.SetType(t.Elem())
900 return n
901 }
902
903
904 func tcUnaryArith(n *ir.UnaryExpr) ir.Node {
905 n.X = Expr(n.X)
906 l := n.X
907 t := l.Type()
908 if t == nil {
909 n.SetType(nil)
910 return n
911 }
912 if !okfor[n.Op()][defaultType(t).Kind()] {
913 base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, n.Op(), typekind(t))
914 n.SetType(nil)
915 return n
916 }
917
918 n.SetType(t)
919 return n
920 }
921
View as plain text