1
2
3
4
5 package ir
6
7 import (
8 "bytes"
9 "cmd/compile/internal/base"
10 "cmd/compile/internal/types"
11 "cmd/internal/obj"
12 "cmd/internal/src"
13 "fmt"
14 "go/constant"
15 "go/token"
16 )
17
18
19 type Expr interface {
20 Node
21 isExpr()
22 }
23
24
25
26
27
28 type miniExpr struct {
29 miniNode
30 flags bitset8
31 typ *types.Type
32 init Nodes
33 }
34
35 const (
36 miniExprNonNil = 1 << iota
37 miniExprTransient
38 miniExprBounded
39 miniExprImplicit
40 miniExprCheckPtr
41 )
42
43 func (*miniExpr) isExpr() {}
44
45 func (n *miniExpr) Type() *types.Type { return n.typ }
46 func (n *miniExpr) SetType(x *types.Type) { n.typ = x }
47 func (n *miniExpr) NonNil() bool { return n.flags&miniExprNonNil != 0 }
48 func (n *miniExpr) MarkNonNil() { n.flags |= miniExprNonNil }
49 func (n *miniExpr) Transient() bool { return n.flags&miniExprTransient != 0 }
50 func (n *miniExpr) SetTransient(b bool) { n.flags.set(miniExprTransient, b) }
51 func (n *miniExpr) Bounded() bool { return n.flags&miniExprBounded != 0 }
52 func (n *miniExpr) SetBounded(b bool) { n.flags.set(miniExprBounded, b) }
53 func (n *miniExpr) Init() Nodes { return n.init }
54 func (n *miniExpr) PtrInit() *Nodes { return &n.init }
55 func (n *miniExpr) SetInit(x Nodes) { n.init = x }
56
57
58 type AddStringExpr struct {
59 miniExpr
60 List Nodes
61 Prealloc *Name
62 }
63
64 func NewAddStringExpr(pos src.XPos, list []Node) *AddStringExpr {
65 n := &AddStringExpr{}
66 n.pos = pos
67 n.op = OADDSTR
68 n.List = list
69 return n
70 }
71
72
73
74 type AddrExpr struct {
75 miniExpr
76 X Node
77 Prealloc *Name
78 }
79
80 func NewAddrExpr(pos src.XPos, x Node) *AddrExpr {
81 if x == nil || x.Typecheck() != 1 {
82 base.FatalfAt(pos, "missed typecheck: %L", x)
83 }
84 n := &AddrExpr{X: x}
85 n.pos = pos
86
87 switch x.Op() {
88 case OARRAYLIT, OMAPLIT, OSLICELIT, OSTRUCTLIT:
89 n.op = OPTRLIT
90
91 default:
92 n.op = OADDR
93 if r, ok := OuterValue(x).(*Name); ok && r.Op() == ONAME {
94 r.SetAddrtaken(true)
95
96
97
98
99
100
101
102
103
104
105 if r.IsClosureVar() && !r.Byval() {
106 r.Canonical().SetAddrtaken(true)
107 }
108 }
109 }
110
111 n.SetType(types.NewPtr(x.Type()))
112 n.SetTypecheck(1)
113
114 return n
115 }
116
117 func (n *AddrExpr) Implicit() bool { return n.flags&miniExprImplicit != 0 }
118 func (n *AddrExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
119
120 func (n *AddrExpr) SetOp(op Op) {
121 switch op {
122 default:
123 panic(n.no("SetOp " + op.String()))
124 case OADDR, OPTRLIT:
125 n.op = op
126 }
127 }
128
129
130 type BasicLit struct {
131 miniExpr
132 val constant.Value
133 }
134
135
136 func NewBasicLit(pos src.XPos, typ *types.Type, val constant.Value) Node {
137 AssertValidTypeForConst(typ, val)
138
139 n := &BasicLit{val: val}
140 n.op = OLITERAL
141 n.pos = pos
142 n.SetType(typ)
143 n.SetTypecheck(1)
144 return n
145 }
146
147 func (n *BasicLit) Val() constant.Value { return n.val }
148 func (n *BasicLit) SetVal(val constant.Value) { n.val = val }
149
150
151
152 func NewConstExpr(val constant.Value, orig Node) Node {
153 return NewBasicLit(orig.Pos(), orig.Type(), val)
154 }
155
156
157
158 type BinaryExpr struct {
159 miniExpr
160 X Node
161 Y Node
162 RType Node `mknode:"-"`
163 }
164
165 func NewBinaryExpr(pos src.XPos, op Op, x, y Node) *BinaryExpr {
166 n := &BinaryExpr{X: x, Y: y}
167 n.pos = pos
168 n.SetOp(op)
169 return n
170 }
171
172 func (n *BinaryExpr) SetOp(op Op) {
173 switch op {
174 default:
175 panic(n.no("SetOp " + op.String()))
176 case OADD, OADDSTR, OAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE,
177 OLSH, OLT, OMOD, OMUL, ONE, OOR, ORSH, OSUB, OXOR,
178 OCOPY, OCOMPLEX, OUNSAFEADD, OUNSAFESLICE, OUNSAFESTRING,
179 OMAKEFACE:
180 n.op = op
181 }
182 }
183
184
185 type CallExpr struct {
186 miniExpr
187 Fun Node
188 Args Nodes
189 DeferAt Node
190 RType Node `mknode:"-"`
191 KeepAlive []*Name
192 IsDDD bool
193 GoDefer bool
194 NoInline bool
195 UseBuf bool
196 AppendNoAlias bool
197
198
199 IsCompilerVarLive bool
200 Reshape bool
201 }
202
203 func NewCallExpr(pos src.XPos, op Op, fun Node, args []Node) *CallExpr {
204 n := &CallExpr{Fun: fun}
205 n.pos = pos
206 n.SetOp(op)
207 n.Args = args
208 return n
209 }
210
211 func (*CallExpr) isStmt() {}
212
213 func (n *CallExpr) SetOp(op Op) {
214 switch op {
215 default:
216 panic(n.no("SetOp " + op.String()))
217 case OAPPEND,
218 OCALL, OCALLFUNC, OCALLINTER, OCALLMETH,
219 ODELETE,
220 OGETG, OGETCALLERSP,
221 OMAKE, OMAX, OMIN, OPRINT, OPRINTLN,
222 ORECOVER:
223 n.op = op
224 }
225 }
226
227
228 type ClosureExpr struct {
229 miniExpr
230 Func *Func `mknode:"-"`
231 Prealloc *Name
232 IsGoWrap bool
233 }
234
235
236
237 type CompLitExpr struct {
238 miniExpr
239 List Nodes
240 RType Node `mknode:"-"`
241 Prealloc *Name
242
243
244
245 Len int64
246 }
247
248 func NewCompLitExpr(pos src.XPos, op Op, typ *types.Type, list []Node) *CompLitExpr {
249 n := &CompLitExpr{List: list}
250 n.pos = pos
251 n.SetOp(op)
252 if typ != nil {
253 n.SetType(typ)
254 }
255 return n
256 }
257
258 func (n *CompLitExpr) Implicit() bool { return n.flags&miniExprImplicit != 0 }
259 func (n *CompLitExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
260
261 func (n *CompLitExpr) SetOp(op Op) {
262 switch op {
263 default:
264 panic(n.no("SetOp " + op.String()))
265 case OARRAYLIT, OCOMPLIT, OMAPLIT, OSTRUCTLIT, OSLICELIT:
266 n.op = op
267 }
268 }
269
270
271
272 type ConvExpr struct {
273 miniExpr
274 X Node
275
276
277
278
279
280
281
282
283
284 TypeWord Node `mknode:"-"`
285 SrcRType Node `mknode:"-"`
286
287
288
289
290
291
292
293
294 ElemRType Node `mknode:"-"`
295 ElemElemRType Node `mknode:"-"`
296 }
297
298 func NewConvExpr(pos src.XPos, op Op, typ *types.Type, x Node) *ConvExpr {
299 n := &ConvExpr{X: x}
300 n.pos = pos
301 n.typ = typ
302 n.SetOp(op)
303 return n
304 }
305
306 func (n *ConvExpr) Implicit() bool { return n.flags&miniExprImplicit != 0 }
307 func (n *ConvExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
308 func (n *ConvExpr) CheckPtr() bool { return n.flags&miniExprCheckPtr != 0 }
309 func (n *ConvExpr) SetCheckPtr(b bool) { n.flags.set(miniExprCheckPtr, b) }
310
311 func (n *ConvExpr) SetOp(op Op) {
312 switch op {
313 default:
314 panic(n.no("SetOp " + op.String()))
315 case OCONV, OCONVIFACE, OCONVNOP, OBYTES2STR, OBYTES2STRTMP, ORUNES2STR, OSTR2BYTES, OSTR2BYTESTMP, OSTR2RUNES, ORUNESTR, OSLICE2ARR, OSLICE2ARRPTR:
316 n.op = op
317 }
318 }
319
320
321 type IndexExpr struct {
322 miniExpr
323 X Node
324 Index Node
325 RType Node `mknode:"-"`
326 Assigned bool
327 }
328
329 func NewIndexExpr(pos src.XPos, x, index Node) *IndexExpr {
330 n := &IndexExpr{X: x, Index: index}
331 n.pos = pos
332 n.op = OINDEX
333 return n
334 }
335
336 func (n *IndexExpr) SetOp(op Op) {
337 switch op {
338 default:
339 panic(n.no("SetOp " + op.String()))
340 case OINDEX, OINDEXMAP:
341 n.op = op
342 }
343 }
344
345
346 type KeyExpr struct {
347 miniExpr
348 Key Node
349 Value Node
350 }
351
352 func NewKeyExpr(pos src.XPos, key, value Node) *KeyExpr {
353 n := &KeyExpr{Key: key, Value: value}
354 n.pos = pos
355 n.op = OKEY
356 return n
357 }
358
359
360 type StructKeyExpr struct {
361 miniExpr
362 Field *types.Field
363 Value Node
364 }
365
366 func NewStructKeyExpr(pos src.XPos, field *types.Field, value Node) *StructKeyExpr {
367 n := &StructKeyExpr{Field: field, Value: value}
368 n.pos = pos
369 n.op = OSTRUCTKEY
370 return n
371 }
372
373 func (n *StructKeyExpr) Sym() *types.Sym { return n.Field.Sym }
374
375
376 type InlinedCallExpr struct {
377 miniExpr
378 Body Nodes
379 ReturnVars Nodes
380 Reshape bool
381 }
382
383 func NewInlinedCallExpr(pos src.XPos, body, retvars []Node) *InlinedCallExpr {
384 n := &InlinedCallExpr{}
385 n.pos = pos
386 n.op = OINLCALL
387 n.Body = body
388 n.ReturnVars = retvars
389 return n
390 }
391
392 func (n *InlinedCallExpr) SingleResult() Node {
393 if have := len(n.ReturnVars); have != 1 {
394 base.FatalfAt(n.Pos(), "inlined call has %v results, expected 1", have)
395 }
396
397
398
399
400 needImplicitConv := !n.Type().HasShape() && n.ReturnVars[0].Type().HasShape()
401 if n.Reshape {
402 needImplicitConv = true
403 }
404
405 if needImplicitConv {
406 r := NewConvExpr(n.Pos(), OCONVNOP, n.Type(), n.ReturnVars[0])
407 r.SetTypecheck(1)
408 return r
409 }
410 return n.ReturnVars[0]
411 }
412
413
414
415
416 type LogicalExpr struct {
417 miniExpr
418 X Node
419 Y Node
420 }
421
422 func NewLogicalExpr(pos src.XPos, op Op, x, y Node) *LogicalExpr {
423 n := &LogicalExpr{X: x, Y: y}
424 n.pos = pos
425 n.SetOp(op)
426 return n
427 }
428
429 func (n *LogicalExpr) SetOp(op Op) {
430 switch op {
431 default:
432 panic(n.no("SetOp " + op.String()))
433 case OANDAND, OOROR:
434 n.op = op
435 }
436 }
437
438
439
440
441 type MakeExpr struct {
442 miniExpr
443 RType Node `mknode:"-"`
444 Len Node
445 Cap Node
446 }
447
448 func NewMakeExpr(pos src.XPos, op Op, len, cap Node) *MakeExpr {
449 n := &MakeExpr{Len: len, Cap: cap}
450 n.pos = pos
451 n.SetOp(op)
452 return n
453 }
454
455 func (n *MakeExpr) SetOp(op Op) {
456 switch op {
457 default:
458 panic(n.no("SetOp " + op.String()))
459 case OMAKECHAN, OMAKEMAP, OMAKESLICE, OMAKESLICECOPY:
460 n.op = op
461 }
462 }
463
464
465 type NilExpr struct {
466 miniExpr
467 }
468
469 func NewNilExpr(pos src.XPos, typ *types.Type) *NilExpr {
470 if typ == nil {
471 base.FatalfAt(pos, "missing type")
472 }
473 n := &NilExpr{}
474 n.pos = pos
475 n.op = ONIL
476 n.SetType(typ)
477 n.SetTypecheck(1)
478 return n
479 }
480
481
482
483 type ParenExpr struct {
484 miniExpr
485 X Node
486 }
487
488 func NewParenExpr(pos src.XPos, x Node) *ParenExpr {
489 n := &ParenExpr{X: x}
490 n.op = OPAREN
491 n.pos = pos
492 return n
493 }
494
495 func (n *ParenExpr) Implicit() bool { return n.flags&miniExprImplicit != 0 }
496 func (n *ParenExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
497
498
499 type ResultExpr struct {
500 miniExpr
501 Index int64
502 }
503
504 func NewResultExpr(pos src.XPos, typ *types.Type, index int64) *ResultExpr {
505 n := &ResultExpr{Index: index}
506 n.pos = pos
507 n.op = ORESULT
508 n.typ = typ
509 return n
510 }
511
512
513
514 type LinksymOffsetExpr struct {
515 miniExpr
516 Linksym *obj.LSym
517 Offset_ int64
518 }
519
520 func NewLinksymOffsetExpr(pos src.XPos, lsym *obj.LSym, offset int64, typ *types.Type) *LinksymOffsetExpr {
521 if typ == nil {
522 base.FatalfAt(pos, "nil type")
523 }
524 n := &LinksymOffsetExpr{Linksym: lsym, Offset_: offset}
525 n.typ = typ
526 n.op = OLINKSYMOFFSET
527 n.SetTypecheck(1)
528 return n
529 }
530
531
532 func NewLinksymExpr(pos src.XPos, lsym *obj.LSym, typ *types.Type) *LinksymOffsetExpr {
533 return NewLinksymOffsetExpr(pos, lsym, 0, typ)
534 }
535
536
537
538 func NewNameOffsetExpr(pos src.XPos, name *Name, offset int64, typ *types.Type) *LinksymOffsetExpr {
539 if name == nil || IsBlank(name) || !(name.Op() == ONAME && name.Class == PEXTERN) {
540 base.FatalfAt(pos, "cannot take offset of nil, blank name or non-global variable: %v", name)
541 }
542 return NewLinksymOffsetExpr(pos, name.Linksym(), offset, typ)
543 }
544
545
546 type SelectorExpr struct {
547 miniExpr
548 X Node
549
550
551
552
553 Sel *types.Sym
554
555 Selection *types.Field
556 Prealloc *Name
557 }
558
559 func NewSelectorExpr(pos src.XPos, op Op, x Node, sel *types.Sym) *SelectorExpr {
560 n := &SelectorExpr{X: x, Sel: sel}
561 n.pos = pos
562 n.SetOp(op)
563 return n
564 }
565
566 func (n *SelectorExpr) SetOp(op Op) {
567 switch op {
568 default:
569 panic(n.no("SetOp " + op.String()))
570 case OXDOT, ODOT, ODOTPTR, ODOTMETH, ODOTINTER, OMETHVALUE, OMETHEXPR:
571 n.op = op
572 }
573 }
574
575 func (n *SelectorExpr) Sym() *types.Sym { return n.Sel }
576 func (n *SelectorExpr) Implicit() bool { return n.flags&miniExprImplicit != 0 }
577 func (n *SelectorExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
578 func (n *SelectorExpr) Offset() int64 { return n.Selection.Offset }
579
580 func (n *SelectorExpr) FuncName() *Name {
581 if n.Op() != OMETHEXPR {
582 panic(n.no("FuncName"))
583 }
584 fn := NewNameAt(n.Selection.Pos, MethodSym(n.X.Type(), n.Sel), n.Type())
585 fn.Class = PFUNC
586 if n.Selection.Nname != nil {
587
588
589
590 fn.Func = n.Selection.Nname.(*Name).Func
591 }
592 return fn
593 }
594
595
596 type SliceExpr struct {
597 miniExpr
598 X Node
599 Low Node
600 High Node
601 Max Node
602 }
603
604 func NewSliceExpr(pos src.XPos, op Op, x, low, high, max Node) *SliceExpr {
605 n := &SliceExpr{X: x, Low: low, High: high, Max: max}
606 n.pos = pos
607 n.op = op
608 return n
609 }
610
611 func (n *SliceExpr) SetOp(op Op) {
612 switch op {
613 default:
614 panic(n.no("SetOp " + op.String()))
615 case OSLICE, OSLICEARR, OSLICESTR, OSLICE3, OSLICE3ARR:
616 n.op = op
617 }
618 }
619
620
621
622 func (o Op) IsSlice3() bool {
623 switch o {
624 case OSLICE, OSLICEARR, OSLICESTR:
625 return false
626 case OSLICE3, OSLICE3ARR:
627 return true
628 }
629 base.Fatalf("IsSlice3 op %v", o)
630 return false
631 }
632
633
634 type SliceHeaderExpr struct {
635 miniExpr
636 Ptr Node
637 Len Node
638 Cap Node
639 }
640
641 func NewSliceHeaderExpr(pos src.XPos, typ *types.Type, ptr, len, cap Node) *SliceHeaderExpr {
642 n := &SliceHeaderExpr{Ptr: ptr, Len: len, Cap: cap}
643 n.pos = pos
644 n.op = OSLICEHEADER
645 n.typ = typ
646 return n
647 }
648
649
650 type StringHeaderExpr struct {
651 miniExpr
652 Ptr Node
653 Len Node
654 }
655
656 func NewStringHeaderExpr(pos src.XPos, ptr, len Node) *StringHeaderExpr {
657 n := &StringHeaderExpr{Ptr: ptr, Len: len}
658 n.pos = pos
659 n.op = OSTRINGHEADER
660 n.typ = types.Types[types.TSTRING]
661 return n
662 }
663
664
665
666 type StarExpr struct {
667 miniExpr
668 X Node
669 }
670
671 func NewStarExpr(pos src.XPos, x Node) *StarExpr {
672 n := &StarExpr{X: x}
673 n.op = ODEREF
674 n.pos = pos
675 return n
676 }
677
678 func (n *StarExpr) Implicit() bool { return n.flags&miniExprImplicit != 0 }
679 func (n *StarExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
680
681
682
683 type TypeAssertExpr struct {
684 miniExpr
685 X Node
686
687
688
689 ITab Node `mknode:"-"`
690
691
692 Descriptor *obj.LSym
693
694
695
696
697 UseNilPanic bool
698 }
699
700 func NewTypeAssertExpr(pos src.XPos, x Node, typ *types.Type) *TypeAssertExpr {
701 n := &TypeAssertExpr{X: x}
702 n.pos = pos
703 n.op = ODOTTYPE
704 if typ != nil {
705 n.SetType(typ)
706 }
707 return n
708 }
709
710 func (n *TypeAssertExpr) SetOp(op Op) {
711 switch op {
712 default:
713 panic(n.no("SetOp " + op.String()))
714 case ODOTTYPE, ODOTTYPE2:
715 n.op = op
716 }
717 }
718
719
720 type DynamicTypeAssertExpr struct {
721 miniExpr
722 X Node
723
724
725
726
727 SrcRType Node
728
729
730
731
732
733 RType Node
734
735
736
737
738
739
740
741
742 ITab Node
743 }
744
745 func NewDynamicTypeAssertExpr(pos src.XPos, op Op, x, rtype Node) *DynamicTypeAssertExpr {
746 n := &DynamicTypeAssertExpr{X: x, RType: rtype}
747 n.pos = pos
748 n.op = op
749 return n
750 }
751
752 func (n *DynamicTypeAssertExpr) SetOp(op Op) {
753 switch op {
754 default:
755 panic(n.no("SetOp " + op.String()))
756 case ODYNAMICDOTTYPE, ODYNAMICDOTTYPE2:
757 n.op = op
758 }
759 }
760
761
762
763 type UnaryExpr struct {
764 miniExpr
765 X Node
766 }
767
768 func NewUnaryExpr(pos src.XPos, op Op, x Node) *UnaryExpr {
769 n := &UnaryExpr{X: x}
770 n.pos = pos
771 n.SetOp(op)
772 return n
773 }
774
775 func (n *UnaryExpr) SetOp(op Op) {
776 switch op {
777 default:
778 panic(n.no("SetOp " + op.String()))
779 case OBITNOT, ONEG, ONOT, OPLUS, ORECV,
780 OCAP, OCLEAR, OCLOSE, OIMAG, OLEN, ONEW, OPANIC, OREAL,
781 OCHECKNIL, OCFUNC, OIDATA, OITAB, OSPTR,
782 OUNSAFESTRINGDATA, OUNSAFESLICEDATA:
783 n.op = op
784 }
785 }
786
787 func IsZero(n Node) bool {
788 switch n.Op() {
789 case ONIL:
790 return true
791
792 case OLITERAL:
793 switch u := n.Val(); u.Kind() {
794 case constant.String:
795 return constant.StringVal(u) == ""
796 case constant.Bool:
797 return !constant.BoolVal(u)
798 default:
799 return constant.Sign(u) == 0
800 }
801
802 case OARRAYLIT:
803 n := n.(*CompLitExpr)
804 for _, n1 := range n.List {
805 if n1.Op() == OKEY {
806 n1 = n1.(*KeyExpr).Value
807 }
808 if !IsZero(n1) {
809 return false
810 }
811 }
812 return true
813
814 case OSTRUCTLIT:
815 n := n.(*CompLitExpr)
816 for _, n1 := range n.List {
817 n1 := n1.(*StructKeyExpr)
818 if !IsZero(n1.Value) {
819 return false
820 }
821 }
822 return true
823 }
824
825 return false
826 }
827
828
829 func IsAddressable(n Node) bool {
830 switch n.Op() {
831 case OINDEX:
832 n := n.(*IndexExpr)
833 if n.X.Type() != nil && n.X.Type().IsArray() {
834 return IsAddressable(n.X)
835 }
836 if n.X.Type() != nil && n.X.Type().IsString() {
837 return false
838 }
839 fallthrough
840 case ODEREF, ODOTPTR:
841 return true
842
843 case ODOT:
844 n := n.(*SelectorExpr)
845 return IsAddressable(n.X)
846
847 case ONAME:
848 n := n.(*Name)
849 if n.Class == PFUNC {
850 return false
851 }
852 return true
853
854 case OLINKSYMOFFSET:
855 return true
856 }
857
858 return false
859 }
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879 func StaticValue(n Node) Node {
880 for {
881 switch n1 := n.(type) {
882 case *ConvExpr:
883 if n1.Op() == OCONVNOP {
884 n = n1.X
885 continue
886 }
887 case *InlinedCallExpr:
888 if n1.Op() == OINLCALL {
889 n = n1.SingleResult()
890 continue
891 }
892 case *ParenExpr:
893 n = n1.X
894 continue
895 }
896
897 n1 := staticValue1(n)
898 if n1 == nil {
899 return n
900 }
901 n = n1
902 }
903 }
904
905 func staticValue1(nn Node) Node {
906 if nn.Op() != ONAME {
907 return nil
908 }
909 n := nn.(*Name).Canonical()
910 if n.Class != PAUTO {
911 return nil
912 }
913
914 defn := n.Defn
915 if defn == nil {
916 return nil
917 }
918
919 var rhs Node
920 FindRHS:
921 switch defn.Op() {
922 case OAS:
923 defn := defn.(*AssignStmt)
924 rhs = defn.Y
925 case OAS2:
926 defn := defn.(*AssignListStmt)
927 for i, lhs := range defn.Lhs {
928 if lhs == n {
929 rhs = defn.Rhs[i]
930 break FindRHS
931 }
932 }
933 base.FatalfAt(defn.Pos(), "%v missing from LHS of %v", n, defn)
934 default:
935 return nil
936 }
937 if rhs == nil {
938 base.FatalfAt(defn.Pos(), "RHS is nil: %v", defn)
939 }
940
941 if Reassigned(n) {
942 return nil
943 }
944
945 return rhs
946 }
947
948
949
950
951
952
953
954
955
956 func Reassigned(name *Name) bool {
957 if name.Op() != ONAME {
958 base.Fatalf("reassigned %v", name)
959 }
960
961 if name.Curfn == nil {
962 return true
963 }
964
965 if name.Addrtaken() {
966 return true
967 }
968
969
970
971
972
973
974 isName := func(x Node) bool {
975 if x == nil {
976 return false
977 }
978 n, ok := OuterValue(x).(*Name)
979 return ok && n.Canonical() == name
980 }
981
982 var do func(n Node) bool
983 do = func(n Node) bool {
984 switch n.Op() {
985 case OAS:
986 n := n.(*AssignStmt)
987 if isName(n.X) && n != name.Defn {
988 return true
989 }
990 case OAS2, OAS2FUNC, OAS2MAPR, OAS2DOTTYPE, OAS2RECV, OSELRECV2:
991 n := n.(*AssignListStmt)
992 for _, p := range n.Lhs {
993 if isName(p) && n != name.Defn {
994 return true
995 }
996 }
997 case OASOP:
998 n := n.(*AssignOpStmt)
999 if isName(n.X) {
1000 return true
1001 }
1002 case OADDR:
1003 n := n.(*AddrExpr)
1004 if isName(n.X) {
1005 base.FatalfAt(n.Pos(), "%v not marked addrtaken", name)
1006 }
1007 case ORANGE:
1008 n := n.(*RangeStmt)
1009 if isName(n.Key) || isName(n.Value) {
1010 return true
1011 }
1012 case OCLOSURE:
1013 n := n.(*ClosureExpr)
1014 if Any(n.Func, do) {
1015 return true
1016 }
1017 }
1018 return false
1019 }
1020 return Any(name.Curfn, do)
1021 }
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035 func FuncSingleAssignment(name *Name) *AssignStmt {
1036 if name.Class != PAUTO {
1037 return nil
1038 }
1039 base.AssertfAt(name.Curfn != nil, name.Pos(), "PAUTO %v has nil Curfn", name)
1040 if name.Addrtaken() {
1041 return nil
1042 }
1043 if name.Type().Kind() != types.TFUNC {
1044 return nil
1045 }
1046
1047
1048
1049 if name.Defn != nil {
1050 as, ok := name.Defn.(*AssignStmt)
1051 if !ok || !isNilAssign(as) {
1052 return nil
1053 }
1054 }
1055
1056 isName := func(x Node) bool {
1057 if x == nil {
1058 return false
1059 }
1060 n, ok := OuterValue(x).(*Name)
1061 return ok && n.Canonical() == name
1062 }
1063
1064 var found *AssignStmt
1065
1066 var do func(n Node) bool
1067 do = func(n Node) bool {
1068 switch n.Op() {
1069 case OAS:
1070 as := n.(*AssignStmt)
1071 if isName(as.X) {
1072 if isNilAssign(as) {
1073 break
1074 }
1075 if found != nil {
1076 found = nil
1077 return true
1078 }
1079 found = as
1080 }
1081 case OAS2, OAS2FUNC, OAS2MAPR, OAS2DOTTYPE, OAS2RECV, OSELRECV2:
1082 as := n.(*AssignListStmt)
1083 for _, p := range as.Lhs {
1084 if isName(p) {
1085 found = nil
1086 return true
1087 }
1088 }
1089 case ORANGE:
1090 rs := n.(*RangeStmt)
1091 if isName(rs.Key) || isName(rs.Value) {
1092 found = nil
1093 return true
1094 }
1095 case OCLOSURE:
1096 n := n.(*ClosureExpr)
1097 if Any(n.Func, do) {
1098 return true
1099 }
1100 }
1101 return false
1102 }
1103
1104 if Any(name.Curfn, do) {
1105 return nil
1106 }
1107 return found
1108 }
1109
1110
1111 func isNilAssign(as *AssignStmt) bool {
1112 if as.Y == nil {
1113 return true
1114 }
1115 y := as.Y
1116 for y.Op() == OCONVNOP {
1117 y = y.(*ConvExpr).X
1118 }
1119 return IsNil(y)
1120 }
1121
1122
1123 func StaticCalleeName(n Node) *Name {
1124 switch n.Op() {
1125 case OMETHEXPR:
1126 n := n.(*SelectorExpr)
1127 return MethodExprName(n)
1128 case ONAME:
1129 n := n.(*Name)
1130 if n.Class == PFUNC {
1131 return n
1132 }
1133 case OCLOSURE:
1134 return n.(*ClosureExpr).Func.Nname
1135 }
1136 return nil
1137 }
1138
1139
1140 var IsIntrinsicCall = func(*CallExpr) bool { return false }
1141
1142
1143 var IsIntrinsicSym = func(*types.Sym) bool { return false }
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160 func SameSafeExpr(l Node, r Node) bool {
1161 for l.Op() == OCONVNOP {
1162 l = l.(*ConvExpr).X
1163 }
1164 for r.Op() == OCONVNOP {
1165 r = r.(*ConvExpr).X
1166 }
1167 if l.Op() != r.Op() || !types.Identical(l.Type(), r.Type()) {
1168 return false
1169 }
1170
1171 switch l.Op() {
1172 case ONAME:
1173 return l == r
1174
1175 case ODOT, ODOTPTR:
1176 l := l.(*SelectorExpr)
1177 r := r.(*SelectorExpr)
1178 return l.Sel != nil && r.Sel != nil && l.Sel == r.Sel && SameSafeExpr(l.X, r.X)
1179
1180 case ODEREF:
1181 l := l.(*StarExpr)
1182 r := r.(*StarExpr)
1183 return SameSafeExpr(l.X, r.X)
1184
1185 case ONOT, OBITNOT, OPLUS, ONEG:
1186 l := l.(*UnaryExpr)
1187 r := r.(*UnaryExpr)
1188 return SameSafeExpr(l.X, r.X)
1189
1190 case OCONV:
1191 l := l.(*ConvExpr)
1192 r := r.(*ConvExpr)
1193
1194
1195 return types.IsSimple[l.Type().Kind()] && SameSafeExpr(l.X, r.X)
1196
1197 case OINDEX, OINDEXMAP:
1198 l := l.(*IndexExpr)
1199 r := r.(*IndexExpr)
1200 return SameSafeExpr(l.X, r.X) && SameSafeExpr(l.Index, r.Index)
1201
1202 case OADD, OSUB, OOR, OXOR, OMUL, OLSH, ORSH, OAND, OANDNOT, ODIV, OMOD:
1203 l := l.(*BinaryExpr)
1204 r := r.(*BinaryExpr)
1205 return SameSafeExpr(l.X, r.X) && SameSafeExpr(l.Y, r.Y)
1206
1207 case OLITERAL:
1208 return constant.Compare(l.Val(), token.EQL, r.Val())
1209
1210 case ONIL:
1211 return true
1212 }
1213
1214 return false
1215 }
1216
1217
1218
1219
1220 func ShouldCheckPtr(fn *Func, level int) bool {
1221 return base.Debug.Checkptr >= level && fn.Pragma&NoCheckPtr == 0
1222 }
1223
1224
1225
1226 func ShouldAsanCheckPtr(fn *Func) bool {
1227 return base.Flag.ASan && fn.Pragma&NoCheckPtr == 0
1228 }
1229
1230
1231
1232 func IsReflectHeaderDataField(l Node) bool {
1233 if l.Type() != types.Types[types.TUINTPTR] {
1234 return false
1235 }
1236
1237 var tsym *types.Sym
1238 switch l.Op() {
1239 case ODOT:
1240 l := l.(*SelectorExpr)
1241 tsym = l.X.Type().Sym()
1242 case ODOTPTR:
1243 l := l.(*SelectorExpr)
1244 tsym = l.X.Type().Elem().Sym()
1245 default:
1246 return false
1247 }
1248
1249 if tsym == nil || l.Sym().Name != "Data" || tsym.Pkg.Path != "reflect" {
1250 return false
1251 }
1252 return tsym.Name == "SliceHeader" || tsym.Name == "StringHeader"
1253 }
1254
1255 func ParamNames(ft *types.Type) []Node {
1256 args := make([]Node, ft.NumParams())
1257 for i, f := range ft.Params() {
1258 args[i] = f.Nname.(*Name)
1259 }
1260 return args
1261 }
1262
1263 func RecvParamNames(ft *types.Type) []Node {
1264 args := make([]Node, ft.NumRecvs()+ft.NumParams())
1265 for i, f := range ft.RecvParams() {
1266 args[i] = f.Nname.(*Name)
1267 }
1268 return args
1269 }
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279 func MethodSym(recv *types.Type, msym *types.Sym) *types.Sym {
1280 sym := MethodSymSuffix(recv, msym, "")
1281 sym.SetFunc(true)
1282 return sym
1283 }
1284
1285
1286
1287
1288 func MethodSymSuffix(recv *types.Type, msym *types.Sym, suffix string) *types.Sym {
1289 if msym.IsBlank() {
1290 base.Fatalf("blank method name")
1291 }
1292
1293 rsym := recv.Sym()
1294 if recv.IsPtr() {
1295 if rsym != nil {
1296 base.Fatalf("declared pointer receiver type: %v", recv)
1297 }
1298 rsym = recv.Elem().Sym()
1299 }
1300
1301
1302
1303
1304 rpkg := Pkgs.Go
1305 if rsym != nil {
1306 rpkg = rsym.Pkg
1307 }
1308
1309 var b bytes.Buffer
1310 if recv.IsPtr() {
1311
1312
1313 fmt.Fprintf(&b, "(%-S)", recv)
1314 } else {
1315 fmt.Fprintf(&b, "%-S", recv)
1316 }
1317
1318
1319
1320
1321
1322 if !types.IsExported(msym.Name) && msym.Pkg != rpkg {
1323 b.WriteString(".")
1324 b.WriteString(msym.Pkg.Prefix)
1325 }
1326
1327 b.WriteString(".")
1328 b.WriteString(msym.Name)
1329 b.WriteString(suffix)
1330 return rpkg.LookupBytes(b.Bytes())
1331 }
1332
1333
1334
1335
1336
1337 func LookupMethodSelector(pkg *types.Pkg, name string) (typ, meth *types.Sym, err error) {
1338 typeName, methName := splitType(name)
1339 if typeName == "" {
1340 return nil, nil, fmt.Errorf("%s doesn't contain type split", name)
1341 }
1342
1343 if len(typeName) > 3 && typeName[:2] == "(*" && typeName[len(typeName)-1] == ')' {
1344
1345
1346 typeName = typeName[2 : len(typeName)-1]
1347 }
1348
1349 typ = pkg.Lookup(typeName)
1350 meth = pkg.Selector(methName)
1351 return typ, meth, nil
1352 }
1353
1354
1355
1356
1357
1358
1359 func splitType(name string) (typ, fn string) {
1360
1361
1362
1363 bracket := 0
1364 for i, r := range name {
1365 if r == '.' && bracket == 0 {
1366 return name[:i], name[i+1:]
1367 }
1368 if r == '[' {
1369 bracket++
1370 }
1371 if r == ']' {
1372 bracket--
1373 }
1374 }
1375 return "", name
1376 }
1377
1378
1379
1380
1381 func MethodExprName(n Node) *Name {
1382 name, _ := MethodExprFunc(n).Nname.(*Name)
1383 return name
1384 }
1385
1386
1387 func MethodExprFunc(n Node) *types.Field {
1388 switch n.Op() {
1389 case ODOTMETH, OMETHEXPR, OMETHVALUE:
1390 return n.(*SelectorExpr).Selection
1391 }
1392 base.Fatalf("unexpected node: %v (%v)", n, n.Op())
1393 panic("unreachable")
1394 }
1395
1396
1397
1398
1399 type MoveToHeapExpr struct {
1400 miniExpr
1401 Slice Node
1402
1403
1404 RType Node
1405
1406
1407
1408
1409
1410
1411 PreserveCapacity bool
1412 }
1413
1414 func NewMoveToHeapExpr(pos src.XPos, slice Node) *MoveToHeapExpr {
1415 n := &MoveToHeapExpr{Slice: slice}
1416 n.pos = pos
1417 n.op = OMOVE2HEAP
1418 return n
1419 }
1420
View as plain text