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