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