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