1
2
3
4
5 package typecheck
6
7 import (
8 "cmd/compile/internal/base"
9 "cmd/compile/internal/ir"
10 "cmd/compile/internal/types"
11 "cmd/internal/src"
12 "internal/types/errors"
13 )
14
15 func RangeExprType(t *types.Type) *types.Type {
16 if t.IsPtr() && t.Elem().IsArray() {
17 return t.Elem()
18 }
19 return t
20 }
21
22 func typecheckrangeExpr(n *ir.RangeStmt) {
23 }
24
25
26
27
28 func tcAssign(n *ir.AssignStmt) {
29 if base.EnableTrace && base.Flag.LowerT {
30 defer tracePrint("tcAssign", n)(nil)
31 }
32
33 if n.Y == nil {
34 n.X = AssignExpr(n.X)
35 return
36 }
37
38 lhs, rhs := []ir.Node{n.X}, []ir.Node{n.Y}
39 assign(n, lhs, rhs)
40 n.X, n.Y = lhs[0], rhs[0]
41
42
43 if !ir.IsBlank(n.X) {
44 types.CheckSize(n.X.Type())
45 }
46 }
47
48 func tcAssignList(n *ir.AssignListStmt) {
49 if base.EnableTrace && base.Flag.LowerT {
50 defer tracePrint("tcAssignList", n)(nil)
51 }
52
53 assign(n, n.Lhs, n.Rhs)
54 }
55
56 func assign(stmt ir.Node, lhs, rhs []ir.Node) {
57
58
59
60
61
62
63
64
65 checkLHS := func(i int, typ *types.Type) {
66 if n := lhs[i]; typ != nil && ir.DeclaredBy(n, stmt) && n.Type() == nil {
67 base.Assertf(typ.Kind() == types.TNIL, "unexpected untyped nil")
68 n.SetType(defaultType(typ))
69 }
70 if lhs[i].Typecheck() == 0 {
71 lhs[i] = AssignExpr(lhs[i])
72 }
73 checkassign(lhs[i])
74 }
75
76 assignType := func(i int, typ *types.Type) {
77 checkLHS(i, typ)
78 if typ != nil {
79 checkassignto(typ, lhs[i])
80 }
81 }
82
83 cr := len(rhs)
84 if len(rhs) == 1 {
85 rhs[0] = typecheck(rhs[0], ctxExpr|ctxMultiOK)
86 if rtyp := rhs[0].Type(); rtyp != nil && rtyp.IsFuncArgStruct() {
87 cr = rtyp.NumFields()
88 }
89 } else {
90 Exprs(rhs)
91 }
92
93
94 assignOK:
95 for len(lhs) == 2 && cr == 1 {
96 stmt := stmt.(*ir.AssignListStmt)
97 r := rhs[0]
98
99 switch r.Op() {
100 case ir.OINDEXMAP:
101 stmt.SetOp(ir.OAS2MAPR)
102 case ir.ORECV:
103 stmt.SetOp(ir.OAS2RECV)
104 case ir.ODOTTYPE:
105 r := r.(*ir.TypeAssertExpr)
106 stmt.SetOp(ir.OAS2DOTTYPE)
107 r.SetOp(ir.ODOTTYPE2)
108 case ir.ODYNAMICDOTTYPE:
109 r := r.(*ir.DynamicTypeAssertExpr)
110 stmt.SetOp(ir.OAS2DOTTYPE)
111 r.SetOp(ir.ODYNAMICDOTTYPE2)
112 default:
113 break assignOK
114 }
115
116 assignType(0, r.Type())
117 assignType(1, types.UntypedBool)
118 return
119 }
120
121 if len(lhs) != cr {
122 if r, ok := rhs[0].(*ir.CallExpr); ok && len(rhs) == 1 {
123 if r.Type() != nil {
124 base.ErrorfAt(stmt.Pos(), errors.WrongAssignCount, "assignment mismatch: %d variable%s but %v returns %d value%s", len(lhs), plural(len(lhs)), r.Fun, cr, plural(cr))
125 }
126 } else {
127 base.ErrorfAt(stmt.Pos(), errors.WrongAssignCount, "assignment mismatch: %d variable%s but %v value%s", len(lhs), plural(len(lhs)), len(rhs), plural(len(rhs)))
128 }
129
130 for i := range lhs {
131 checkLHS(i, nil)
132 }
133 return
134 }
135
136
137 if cr > len(rhs) {
138 stmt := stmt.(*ir.AssignListStmt)
139 stmt.SetOp(ir.OAS2FUNC)
140 r := rhs[0].(*ir.CallExpr)
141 rtyp := r.Type()
142
143 mismatched := false
144 failed := false
145 for i := range lhs {
146 result := rtyp.Field(i).Type
147 assignType(i, result)
148
149 if lhs[i].Type() == nil || result == nil {
150 failed = true
151 } else if lhs[i] != ir.BlankNode && !types.Identical(lhs[i].Type(), result) {
152 mismatched = true
153 }
154 }
155 if mismatched && !failed {
156 RewriteMultiValueCall(stmt, r)
157 }
158 return
159 }
160
161 for i, r := range rhs {
162 checkLHS(i, r.Type())
163 if lhs[i].Type() != nil {
164 rhs[i] = AssignConv(r, lhs[i].Type(), "assignment")
165 }
166 }
167 }
168
169 func plural(n int) string {
170 if n == 1 {
171 return ""
172 }
173 return "s"
174 }
175
176
177 func tcCheckNil(n *ir.UnaryExpr) ir.Node {
178 n.X = Expr(n.X)
179 if !n.X.Type().IsPtrShaped() {
180 base.FatalfAt(n.Pos(), "%L is not pointer shaped", n.X)
181 }
182 return n
183 }
184
185
186 func tcFor(n *ir.ForStmt) ir.Node {
187 Stmts(n.Init())
188 n.Cond = Expr(n.Cond)
189 n.Cond = DefaultLit(n.Cond, nil)
190 if n.Cond != nil {
191 t := n.Cond.Type()
192 if t != nil && !t.IsBoolean() {
193 base.Errorf("non-bool %L used as for condition", n.Cond)
194 }
195 }
196 n.Post = Stmt(n.Post)
197 Stmts(n.Body)
198 return n
199 }
200
201
202 func tcGoDefer(n *ir.GoDeferStmt) {
203 call := normalizeGoDeferCall(n.Pos(), n.Op(), n.Call, n.PtrInit())
204 call.GoDefer = true
205 n.Call = call
206 }
207
208
209
210
211
212
213
214
215
216
217
218
219
220 func normalizeGoDeferCall(pos src.XPos, op ir.Op, call ir.Node, init *ir.Nodes) *ir.CallExpr {
221 init.Append(ir.TakeInit(call)...)
222
223 if call, ok := call.(*ir.CallExpr); ok && call.Op() == ir.OCALLFUNC {
224 if sig := call.Fun.Type(); sig.NumParams()+sig.NumResults() == 0 {
225 return call
226 }
227 }
228
229
230 wrapperFn := ir.NewClosureFunc(pos, pos, op, types.NewSignature(nil, nil, nil), ir.CurFunc, Target)
231 wrapperFn.DeclareParams(true)
232 wrapperFn.SetWrapper(true)
233
234
235
236 var argps []*ir.Node
237
238 var visit func(argp *ir.Node)
239 visit = func(argp *ir.Node) {
240 arg := *argp
241 if arg == nil {
242 return
243 }
244
245
246
247
248 switch arg.Op() {
249 case ir.OLITERAL, ir.ONIL, ir.OMETHEXPR, ir.ONEW:
250 return
251 case ir.ONAME:
252 arg := arg.(*ir.Name)
253 if arg.Class == ir.PFUNC {
254 return
255 }
256 case ir.OADDR:
257 arg := arg.(*ir.AddrExpr)
258 if arg.X.Op() == ir.OLINKSYMOFFSET {
259 return
260 }
261
262 case ir.OCONVNOP:
263 arg := arg.(*ir.ConvExpr)
264
265
266
267
268
269
270
271 if arg.Type().IsUintptr() && arg.X.Type().IsUnsafePtr() {
272 visit(&arg.X)
273 return
274 }
275
276 case ir.OARRAYLIT, ir.OSLICELIT, ir.OSTRUCTLIT:
277
278
279 list := arg.(*ir.CompLitExpr).List
280 for i, el := range list {
281 switch el := el.(type) {
282 case *ir.KeyExpr:
283 visit(&el.Value)
284 case *ir.StructKeyExpr:
285 visit(&el.Value)
286 default:
287 visit(&list[i])
288 }
289 }
290 return
291 }
292
293 argps = append(argps, argp)
294 }
295
296 visitList := func(list []ir.Node) {
297 for i := range list {
298 visit(&list[i])
299 }
300 }
301
302 switch call.Op() {
303 default:
304 base.Fatalf("unexpected call op: %v", call.Op())
305
306 case ir.OCALLFUNC:
307 call := call.(*ir.CallExpr)
308
309
310 if wrapped := ir.StaticCalleeName(call.Fun); wrapped != nil {
311 wrapperFn.WrappedFunc = wrapped.Func
312 }
313
314 visit(&call.Fun)
315 visitList(call.Args)
316
317 case ir.OCALLINTER:
318 call := call.(*ir.CallExpr)
319 argps = append(argps, &call.Fun.(*ir.SelectorExpr).X)
320 visitList(call.Args)
321
322 case ir.OAPPEND, ir.ODELETE, ir.OPRINT, ir.OPRINTLN, ir.ORECOVERFP:
323 call := call.(*ir.CallExpr)
324 visitList(call.Args)
325 visit(&call.RType)
326
327 case ir.OCOPY:
328 call := call.(*ir.BinaryExpr)
329 visit(&call.X)
330 visit(&call.Y)
331 visit(&call.RType)
332
333 case ir.OCLEAR, ir.OCLOSE, ir.OPANIC:
334 call := call.(*ir.UnaryExpr)
335 visit(&call.X)
336 }
337
338 if len(argps) != 0 {
339
340
341
342
343 stmtPos := base.Pos
344 callPos := base.Pos
345
346 as := ir.NewAssignListStmt(callPos, ir.OAS2, make([]ir.Node, len(argps)), make([]ir.Node, len(argps)))
347 for i, argp := range argps {
348 arg := *argp
349
350 pos := callPos
351 if ir.HasUniquePos(arg) {
352 pos = arg.Pos()
353 }
354
355
356 tmp := TempAt(pos, ir.CurFunc, arg.Type())
357 init.Append(Stmt(ir.NewDecl(pos, ir.ODCL, tmp)))
358 tmp.Defn = as
359 as.Lhs[i] = tmp
360 as.Rhs[i] = arg
361
362
363 *argp = ir.NewClosureVar(pos, wrapperFn, tmp)
364 }
365 init.Append(Stmt(as))
366
367
368
369 if call.Op() == ir.OCALLINTER {
370 iface := as.Lhs[0]
371 init.Append(Stmt(ir.NewUnaryExpr(stmtPos, ir.OCHECKNIL, ir.NewUnaryExpr(iface.Pos(), ir.OITAB, iface))))
372 }
373 }
374
375
376
377 wrapperFn.Body = []ir.Node{call}
378
379
380 return Call(call.Pos(), wrapperFn.OClosure, nil, false).(*ir.CallExpr)
381 }
382
383
384 func tcIf(n *ir.IfStmt) ir.Node {
385 Stmts(n.Init())
386 n.Cond = Expr(n.Cond)
387 n.Cond = DefaultLit(n.Cond, nil)
388 if n.Cond != nil {
389 t := n.Cond.Type()
390 if t != nil && !t.IsBoolean() {
391 base.Errorf("non-bool %L used as if condition", n.Cond)
392 }
393 }
394 Stmts(n.Body)
395 Stmts(n.Else)
396 return n
397 }
398
399
400 func tcRange(n *ir.RangeStmt) {
401 n.X = Expr(n.X)
402
403
404 if n.Key != nil {
405 if !ir.DeclaredBy(n.Key, n) {
406 n.Key = AssignExpr(n.Key)
407 }
408 checkassign(n.Key)
409 }
410 if n.Value != nil {
411 if !ir.DeclaredBy(n.Value, n) {
412 n.Value = AssignExpr(n.Value)
413 }
414 checkassign(n.Value)
415 }
416
417
418 n.SetTypecheck(1)
419 if n.Key != nil && n.Key.Typecheck() == 0 {
420 n.Key = AssignExpr(n.Key)
421 }
422 if n.Value != nil && n.Value.Typecheck() == 0 {
423 n.Value = AssignExpr(n.Value)
424 }
425
426 Stmts(n.Body)
427 }
428
429
430 func tcReturn(n *ir.ReturnStmt) ir.Node {
431 if ir.CurFunc == nil {
432 base.FatalfAt(n.Pos(), "return outside function")
433 }
434
435 typecheckargs(n)
436 if len(n.Results) != 0 {
437 typecheckaste(ir.ORETURN, nil, false, ir.CurFunc.Type().Results(), n.Results, func() string { return "return argument" })
438 }
439 return n
440 }
441
442
443 func tcSelect(sel *ir.SelectStmt) {
444 var def *ir.CommClause
445 lno := ir.SetPos(sel)
446 Stmts(sel.Init())
447 for _, ncase := range sel.Cases {
448 if ncase.Comm == nil {
449
450 if def != nil {
451 base.ErrorfAt(ncase.Pos(), errors.DuplicateDefault, "multiple defaults in select (first at %v)", ir.Line(def))
452 } else {
453 def = ncase
454 }
455 } else {
456 n := Stmt(ncase.Comm)
457 ncase.Comm = n
458 oselrecv2 := func(dst, recv ir.Node, def bool) {
459 selrecv := ir.NewAssignListStmt(n.Pos(), ir.OSELRECV2, []ir.Node{dst, ir.BlankNode}, []ir.Node{recv})
460 selrecv.Def = def
461 selrecv.SetTypecheck(1)
462 selrecv.SetInit(n.Init())
463 ncase.Comm = selrecv
464 }
465 switch n.Op() {
466 default:
467 pos := n.Pos()
468 if n.Op() == ir.ONAME {
469
470
471
472
473 pos = ncase.Pos()
474 }
475 base.ErrorfAt(pos, errors.InvalidSelectCase, "select case must be receive, send or assign recv")
476
477 case ir.OAS:
478
479
480
481 n := n.(*ir.AssignStmt)
482 if r := n.Y; r.Op() == ir.OCONVNOP || r.Op() == ir.OCONVIFACE {
483 r := r.(*ir.ConvExpr)
484 if r.Implicit() {
485 n.Y = r.X
486 }
487 }
488 if n.Y.Op() != ir.ORECV {
489 base.ErrorfAt(n.Pos(), errors.InvalidSelectCase, "select assignment must have receive on right hand side")
490 break
491 }
492 oselrecv2(n.X, n.Y, n.Def)
493
494 case ir.OAS2RECV:
495 n := n.(*ir.AssignListStmt)
496 if n.Rhs[0].Op() != ir.ORECV {
497 base.ErrorfAt(n.Pos(), errors.InvalidSelectCase, "select assignment must have receive on right hand side")
498 break
499 }
500 n.SetOp(ir.OSELRECV2)
501
502 case ir.ORECV:
503
504 n := n.(*ir.UnaryExpr)
505 oselrecv2(ir.BlankNode, n, false)
506
507 case ir.OSEND:
508 break
509 }
510 }
511
512 Stmts(ncase.Body)
513 }
514
515 base.Pos = lno
516 }
517
518
519 func tcSend(n *ir.SendStmt) ir.Node {
520 n.Chan = Expr(n.Chan)
521 n.Value = Expr(n.Value)
522 n.Chan = DefaultLit(n.Chan, nil)
523 t := n.Chan.Type()
524 if t == nil {
525 return n
526 }
527 if !t.IsChan() {
528 base.Errorf("invalid operation: %v (send to non-chan type %v)", n, t)
529 return n
530 }
531
532 if !t.ChanDir().CanSend() {
533 base.Errorf("invalid operation: %v (send to receive-only type %v)", n, t)
534 return n
535 }
536
537 n.Value = AssignConv(n.Value, t.Elem(), "send")
538 if n.Value.Type() == nil {
539 return n
540 }
541 return n
542 }
543
544
545 func tcSwitch(n *ir.SwitchStmt) {
546 Stmts(n.Init())
547 if n.Tag != nil && n.Tag.Op() == ir.OTYPESW {
548 tcSwitchType(n)
549 } else {
550 tcSwitchExpr(n)
551 }
552 }
553
554 func tcSwitchExpr(n *ir.SwitchStmt) {
555 t := types.Types[types.TBOOL]
556 if n.Tag != nil {
557 n.Tag = Expr(n.Tag)
558 n.Tag = DefaultLit(n.Tag, nil)
559 t = n.Tag.Type()
560 }
561
562 var nilonly string
563 if t != nil {
564 switch {
565 case t.IsMap():
566 nilonly = "map"
567 case t.Kind() == types.TFUNC:
568 nilonly = "func"
569 case t.IsSlice():
570 nilonly = "slice"
571
572 case !types.IsComparable(t):
573 if t.IsStruct() {
574 base.ErrorfAt(n.Pos(), errors.InvalidExprSwitch, "cannot switch on %L (struct containing %v cannot be compared)", n.Tag, types.IncomparableField(t).Type)
575 } else {
576 base.ErrorfAt(n.Pos(), errors.InvalidExprSwitch, "cannot switch on %L", n.Tag)
577 }
578 t = nil
579 }
580 }
581
582 var defCase ir.Node
583 for _, ncase := range n.Cases {
584 ls := ncase.List
585 if len(ls) == 0 {
586 if defCase != nil {
587 base.ErrorfAt(ncase.Pos(), errors.DuplicateDefault, "multiple defaults in switch (first at %v)", ir.Line(defCase))
588 } else {
589 defCase = ncase
590 }
591 }
592
593 for i := range ls {
594 ir.SetPos(ncase)
595 ls[i] = Expr(ls[i])
596 ls[i] = DefaultLit(ls[i], t)
597 n1 := ls[i]
598 if t == nil || n1.Type() == nil {
599 continue
600 }
601
602 if nilonly != "" && !ir.IsNil(n1) {
603 base.ErrorfAt(ncase.Pos(), errors.MismatchedTypes, "invalid case %v in switch (can only compare %s %v to nil)", n1, nilonly, n.Tag)
604 } else if t.IsInterface() && !n1.Type().IsInterface() && !types.IsComparable(n1.Type()) {
605 base.ErrorfAt(ncase.Pos(), errors.UndefinedOp, "invalid case %L in switch (incomparable type)", n1)
606 } else {
607 op1, _ := assignOp(n1.Type(), t)
608 op2, _ := assignOp(t, n1.Type())
609 if op1 == ir.OXXX && op2 == ir.OXXX {
610 if n.Tag != nil {
611 base.ErrorfAt(ncase.Pos(), errors.MismatchedTypes, "invalid case %v in switch on %v (mismatched types %v and %v)", n1, n.Tag, n1.Type(), t)
612 } else {
613 base.ErrorfAt(ncase.Pos(), errors.MismatchedTypes, "invalid case %v in switch (mismatched types %v and bool)", n1, n1.Type())
614 }
615 }
616 }
617 }
618
619 Stmts(ncase.Body)
620 }
621 }
622
623 func tcSwitchType(n *ir.SwitchStmt) {
624 guard := n.Tag.(*ir.TypeSwitchGuard)
625 guard.X = Expr(guard.X)
626 t := guard.X.Type()
627 if t != nil && !t.IsInterface() {
628 base.ErrorfAt(n.Pos(), errors.InvalidTypeSwitch, "cannot type switch on non-interface value %L", guard.X)
629 t = nil
630 }
631
632
633
634
635 if v := guard.Tag; v != nil && !ir.IsBlank(v) && len(n.Cases) == 0 {
636 base.ErrorfAt(v.Pos(), errors.UnusedVar, "%v declared but not used", v.Sym())
637 }
638
639 var defCase, nilCase ir.Node
640 var ts typeSet
641 for _, ncase := range n.Cases {
642 ls := ncase.List
643 if len(ls) == 0 {
644 if defCase != nil {
645 base.ErrorfAt(ncase.Pos(), errors.DuplicateDefault, "multiple defaults in switch (first at %v)", ir.Line(defCase))
646 } else {
647 defCase = ncase
648 }
649 }
650
651 for i := range ls {
652 ls[i] = typecheck(ls[i], ctxExpr|ctxType)
653 n1 := ls[i]
654 if t == nil || n1.Type() == nil {
655 continue
656 }
657
658 if ir.IsNil(n1) {
659 if nilCase != nil {
660 base.ErrorfAt(ncase.Pos(), errors.DuplicateCase, "multiple nil cases in type switch (first at %v)", ir.Line(nilCase))
661 } else {
662 nilCase = ncase
663 }
664 continue
665 }
666 if n1.Op() == ir.ODYNAMICTYPE {
667 continue
668 }
669 if n1.Op() != ir.OTYPE {
670 base.ErrorfAt(ncase.Pos(), errors.NotAType, "%L is not a type", n1)
671 continue
672 }
673 if !n1.Type().IsInterface() {
674 why := ImplementsExplain(n1.Type(), t)
675 if why != "" {
676 base.ErrorfAt(ncase.Pos(), errors.ImpossibleAssert, "impossible type switch case: %L cannot have dynamic type %v (%s)", guard.X, n1.Type(), why)
677 }
678 continue
679 }
680
681 ts.add(ncase.Pos(), n1.Type())
682 }
683
684 if ncase.Var != nil {
685
686 vt := t
687 if len(ls) == 1 {
688 if ls[0].Op() == ir.OTYPE || ls[0].Op() == ir.ODYNAMICTYPE {
689 vt = ls[0].Type()
690 } else if !ir.IsNil(ls[0]) {
691
692
693 vt = nil
694 }
695 }
696
697 nvar := ncase.Var
698 nvar.SetType(vt)
699 if vt != nil {
700 nvar = AssignExpr(nvar).(*ir.Name)
701 } else {
702
703 nvar.SetTypecheck(1)
704 }
705 ncase.Var = nvar
706 }
707
708 Stmts(ncase.Body)
709 }
710 }
711
712 type typeSet struct {
713 m map[string]src.XPos
714 }
715
716 func (s *typeSet) add(pos src.XPos, typ *types.Type) {
717 if s.m == nil {
718 s.m = make(map[string]src.XPos)
719 }
720
721 ls := typ.LinkString()
722 if prev, ok := s.m[ls]; ok {
723 base.ErrorfAt(pos, errors.DuplicateCase, "duplicate case %v in type switch\n\tprevious case at %s", typ, base.FmtPos(prev))
724 return
725 }
726 s.m[ls] = pos
727 }
728
View as plain text