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 }
196
197 func NewCallExpr(pos src.XPos, op Op, fun Node, args []Node) *CallExpr {
198 n := &CallExpr{Fun: fun}
199 n.pos = pos
200 n.SetOp(op)
201 n.Args = args
202 return n
203 }
204
205 func (*CallExpr) isStmt() {}
206
207 func (n *CallExpr) SetOp(op Op) {
208 switch op {
209 default:
210 panic(n.no("SetOp " + op.String()))
211 case OAPPEND,
212 OCALL, OCALLFUNC, OCALLINTER, OCALLMETH,
213 ODELETE,
214 OGETG, OGETCALLERSP,
215 OMAKE, OMAX, OMIN, OPRINT, OPRINTLN,
216 ORECOVER:
217 n.op = op
218 }
219 }
220
221
222 type ClosureExpr struct {
223 miniExpr
224 Func *Func `mknode:"-"`
225 Prealloc *Name
226 IsGoWrap bool
227 }
228
229
230
231 type CompLitExpr struct {
232 miniExpr
233 List Nodes
234 RType Node `mknode:"-"`
235 Prealloc *Name
236
237
238
239 Len int64
240 }
241
242 func NewCompLitExpr(pos src.XPos, op Op, typ *types.Type, list []Node) *CompLitExpr {
243 n := &CompLitExpr{List: list}
244 n.pos = pos
245 n.SetOp(op)
246 if typ != nil {
247 n.SetType(typ)
248 }
249 return n
250 }
251
252 func (n *CompLitExpr) Implicit() bool { return n.flags&miniExprImplicit != 0 }
253 func (n *CompLitExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
254
255 func (n *CompLitExpr) SetOp(op Op) {
256 switch op {
257 default:
258 panic(n.no("SetOp " + op.String()))
259 case OARRAYLIT, OCOMPLIT, OMAPLIT, OSTRUCTLIT, OSLICELIT:
260 n.op = op
261 }
262 }
263
264
265
266 type ConvExpr struct {
267 miniExpr
268 X Node
269
270
271
272
273
274
275
276
277
278 TypeWord Node `mknode:"-"`
279 SrcRType Node `mknode:"-"`
280
281
282
283
284
285
286
287
288 ElemRType Node `mknode:"-"`
289 ElemElemRType Node `mknode:"-"`
290 }
291
292 func NewConvExpr(pos src.XPos, op Op, typ *types.Type, x Node) *ConvExpr {
293 n := &ConvExpr{X: x}
294 n.pos = pos
295 n.typ = typ
296 n.SetOp(op)
297 return n
298 }
299
300 func (n *ConvExpr) Implicit() bool { return n.flags&miniExprImplicit != 0 }
301 func (n *ConvExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
302 func (n *ConvExpr) CheckPtr() bool { return n.flags&miniExprCheckPtr != 0 }
303 func (n *ConvExpr) SetCheckPtr(b bool) { n.flags.set(miniExprCheckPtr, b) }
304
305 func (n *ConvExpr) SetOp(op Op) {
306 switch op {
307 default:
308 panic(n.no("SetOp " + op.String()))
309 case OCONV, OCONVIFACE, OCONVNOP, OBYTES2STR, OBYTES2STRTMP, ORUNES2STR, OSTR2BYTES, OSTR2BYTESTMP, OSTR2RUNES, ORUNESTR, OSLICE2ARR, OSLICE2ARRPTR:
310 n.op = op
311 }
312 }
313
314
315 type IndexExpr struct {
316 miniExpr
317 X Node
318 Index Node
319 RType Node `mknode:"-"`
320 Assigned bool
321 }
322
323 func NewIndexExpr(pos src.XPos, x, index Node) *IndexExpr {
324 n := &IndexExpr{X: x, Index: index}
325 n.pos = pos
326 n.op = OINDEX
327 return n
328 }
329
330 func (n *IndexExpr) SetOp(op Op) {
331 switch op {
332 default:
333 panic(n.no("SetOp " + op.String()))
334 case OINDEX, OINDEXMAP:
335 n.op = op
336 }
337 }
338
339
340 type KeyExpr struct {
341 miniExpr
342 Key Node
343 Value Node
344 }
345
346 func NewKeyExpr(pos src.XPos, key, value Node) *KeyExpr {
347 n := &KeyExpr{Key: key, Value: value}
348 n.pos = pos
349 n.op = OKEY
350 return n
351 }
352
353
354 type StructKeyExpr struct {
355 miniExpr
356 Field *types.Field
357 Value Node
358 }
359
360 func NewStructKeyExpr(pos src.XPos, field *types.Field, value Node) *StructKeyExpr {
361 n := &StructKeyExpr{Field: field, Value: value}
362 n.pos = pos
363 n.op = OSTRUCTKEY
364 return n
365 }
366
367 func (n *StructKeyExpr) Sym() *types.Sym { return n.Field.Sym }
368
369
370 type InlinedCallExpr struct {
371 miniExpr
372 Body Nodes
373 ReturnVars Nodes
374 }
375
376 func NewInlinedCallExpr(pos src.XPos, body, retvars []Node) *InlinedCallExpr {
377 n := &InlinedCallExpr{}
378 n.pos = pos
379 n.op = OINLCALL
380 n.Body = body
381 n.ReturnVars = retvars
382 return n
383 }
384
385 func (n *InlinedCallExpr) SingleResult() Node {
386 if have := len(n.ReturnVars); have != 1 {
387 base.FatalfAt(n.Pos(), "inlined call has %v results, expected 1", have)
388 }
389 if !n.Type().HasShape() && n.ReturnVars[0].Type().HasShape() {
390
391
392
393 r := NewConvExpr(n.Pos(), OCONVNOP, n.Type(), n.ReturnVars[0])
394 r.SetTypecheck(1)
395 return r
396 }
397 return n.ReturnVars[0]
398 }
399
400
401
402
403 type LogicalExpr struct {
404 miniExpr
405 X Node
406 Y Node
407 }
408
409 func NewLogicalExpr(pos src.XPos, op Op, x, y Node) *LogicalExpr {
410 n := &LogicalExpr{X: x, Y: y}
411 n.pos = pos
412 n.SetOp(op)
413 return n
414 }
415
416 func (n *LogicalExpr) SetOp(op Op) {
417 switch op {
418 default:
419 panic(n.no("SetOp " + op.String()))
420 case OANDAND, OOROR:
421 n.op = op
422 }
423 }
424
425
426
427
428 type MakeExpr struct {
429 miniExpr
430 RType Node `mknode:"-"`
431 Len Node
432 Cap Node
433 }
434
435 func NewMakeExpr(pos src.XPos, op Op, len, cap Node) *MakeExpr {
436 n := &MakeExpr{Len: len, Cap: cap}
437 n.pos = pos
438 n.SetOp(op)
439 return n
440 }
441
442 func (n *MakeExpr) SetOp(op Op) {
443 switch op {
444 default:
445 panic(n.no("SetOp " + op.String()))
446 case OMAKECHAN, OMAKEMAP, OMAKESLICE, OMAKESLICECOPY:
447 n.op = op
448 }
449 }
450
451
452 type NilExpr struct {
453 miniExpr
454 }
455
456 func NewNilExpr(pos src.XPos, typ *types.Type) *NilExpr {
457 if typ == nil {
458 base.FatalfAt(pos, "missing type")
459 }
460 n := &NilExpr{}
461 n.pos = pos
462 n.op = ONIL
463 n.SetType(typ)
464 n.SetTypecheck(1)
465 return n
466 }
467
468
469
470 type ParenExpr struct {
471 miniExpr
472 X Node
473 }
474
475 func NewParenExpr(pos src.XPos, x Node) *ParenExpr {
476 n := &ParenExpr{X: x}
477 n.op = OPAREN
478 n.pos = pos
479 return n
480 }
481
482 func (n *ParenExpr) Implicit() bool { return n.flags&miniExprImplicit != 0 }
483 func (n *ParenExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
484
485
486 type ResultExpr struct {
487 miniExpr
488 Index int64
489 }
490
491 func NewResultExpr(pos src.XPos, typ *types.Type, index int64) *ResultExpr {
492 n := &ResultExpr{Index: index}
493 n.pos = pos
494 n.op = ORESULT
495 n.typ = typ
496 return n
497 }
498
499
500
501 type LinksymOffsetExpr struct {
502 miniExpr
503 Linksym *obj.LSym
504 Offset_ int64
505 }
506
507 func NewLinksymOffsetExpr(pos src.XPos, lsym *obj.LSym, offset int64, typ *types.Type) *LinksymOffsetExpr {
508 if typ == nil {
509 base.FatalfAt(pos, "nil type")
510 }
511 n := &LinksymOffsetExpr{Linksym: lsym, Offset_: offset}
512 n.typ = typ
513 n.op = OLINKSYMOFFSET
514 n.SetTypecheck(1)
515 return n
516 }
517
518
519 func NewLinksymExpr(pos src.XPos, lsym *obj.LSym, typ *types.Type) *LinksymOffsetExpr {
520 return NewLinksymOffsetExpr(pos, lsym, 0, typ)
521 }
522
523
524
525 func NewNameOffsetExpr(pos src.XPos, name *Name, offset int64, typ *types.Type) *LinksymOffsetExpr {
526 if name == nil || IsBlank(name) || !(name.Op() == ONAME && name.Class == PEXTERN) {
527 base.FatalfAt(pos, "cannot take offset of nil, blank name or non-global variable: %v", name)
528 }
529 return NewLinksymOffsetExpr(pos, name.Linksym(), offset, typ)
530 }
531
532
533 type SelectorExpr struct {
534 miniExpr
535 X Node
536
537
538
539
540 Sel *types.Sym
541
542 Selection *types.Field
543 Prealloc *Name
544 }
545
546 func NewSelectorExpr(pos src.XPos, op Op, x Node, sel *types.Sym) *SelectorExpr {
547 n := &SelectorExpr{X: x, Sel: sel}
548 n.pos = pos
549 n.SetOp(op)
550 return n
551 }
552
553 func (n *SelectorExpr) SetOp(op Op) {
554 switch op {
555 default:
556 panic(n.no("SetOp " + op.String()))
557 case OXDOT, ODOT, ODOTPTR, ODOTMETH, ODOTINTER, OMETHVALUE, OMETHEXPR:
558 n.op = op
559 }
560 }
561
562 func (n *SelectorExpr) Sym() *types.Sym { return n.Sel }
563 func (n *SelectorExpr) Implicit() bool { return n.flags&miniExprImplicit != 0 }
564 func (n *SelectorExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
565 func (n *SelectorExpr) Offset() int64 { return n.Selection.Offset }
566
567 func (n *SelectorExpr) FuncName() *Name {
568 if n.Op() != OMETHEXPR {
569 panic(n.no("FuncName"))
570 }
571 fn := NewNameAt(n.Selection.Pos, MethodSym(n.X.Type(), n.Sel), n.Type())
572 fn.Class = PFUNC
573 if n.Selection.Nname != nil {
574
575
576
577 fn.Func = n.Selection.Nname.(*Name).Func
578 }
579 return fn
580 }
581
582
583 type SliceExpr struct {
584 miniExpr
585 X Node
586 Low Node
587 High Node
588 Max Node
589 }
590
591 func NewSliceExpr(pos src.XPos, op Op, x, low, high, max Node) *SliceExpr {
592 n := &SliceExpr{X: x, Low: low, High: high, Max: max}
593 n.pos = pos
594 n.op = op
595 return n
596 }
597
598 func (n *SliceExpr) SetOp(op Op) {
599 switch op {
600 default:
601 panic(n.no("SetOp " + op.String()))
602 case OSLICE, OSLICEARR, OSLICESTR, OSLICE3, OSLICE3ARR:
603 n.op = op
604 }
605 }
606
607
608
609 func (o Op) IsSlice3() bool {
610 switch o {
611 case OSLICE, OSLICEARR, OSLICESTR:
612 return false
613 case OSLICE3, OSLICE3ARR:
614 return true
615 }
616 base.Fatalf("IsSlice3 op %v", o)
617 return false
618 }
619
620
621 type SliceHeaderExpr struct {
622 miniExpr
623 Ptr Node
624 Len Node
625 Cap Node
626 }
627
628 func NewSliceHeaderExpr(pos src.XPos, typ *types.Type, ptr, len, cap Node) *SliceHeaderExpr {
629 n := &SliceHeaderExpr{Ptr: ptr, Len: len, Cap: cap}
630 n.pos = pos
631 n.op = OSLICEHEADER
632 n.typ = typ
633 return n
634 }
635
636
637 type StringHeaderExpr struct {
638 miniExpr
639 Ptr Node
640 Len Node
641 }
642
643 func NewStringHeaderExpr(pos src.XPos, ptr, len Node) *StringHeaderExpr {
644 n := &StringHeaderExpr{Ptr: ptr, Len: len}
645 n.pos = pos
646 n.op = OSTRINGHEADER
647 n.typ = types.Types[types.TSTRING]
648 return n
649 }
650
651
652
653 type StarExpr struct {
654 miniExpr
655 X Node
656 }
657
658 func NewStarExpr(pos src.XPos, x Node) *StarExpr {
659 n := &StarExpr{X: x}
660 n.op = ODEREF
661 n.pos = pos
662 return n
663 }
664
665 func (n *StarExpr) Implicit() bool { return n.flags&miniExprImplicit != 0 }
666 func (n *StarExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
667
668
669
670 type TypeAssertExpr struct {
671 miniExpr
672 X Node
673
674
675
676 ITab Node `mknode:"-"`
677
678
679 Descriptor *obj.LSym
680
681
682
683
684 UseNilPanic bool
685 }
686
687 func NewTypeAssertExpr(pos src.XPos, x Node, typ *types.Type) *TypeAssertExpr {
688 n := &TypeAssertExpr{X: x}
689 n.pos = pos
690 n.op = ODOTTYPE
691 if typ != nil {
692 n.SetType(typ)
693 }
694 return n
695 }
696
697 func (n *TypeAssertExpr) SetOp(op Op) {
698 switch op {
699 default:
700 panic(n.no("SetOp " + op.String()))
701 case ODOTTYPE, ODOTTYPE2:
702 n.op = op
703 }
704 }
705
706
707 type DynamicTypeAssertExpr struct {
708 miniExpr
709 X Node
710
711
712
713
714 SrcRType Node
715
716
717
718
719
720 RType Node
721
722
723
724
725
726
727
728
729 ITab Node
730 }
731
732 func NewDynamicTypeAssertExpr(pos src.XPos, op Op, x, rtype Node) *DynamicTypeAssertExpr {
733 n := &DynamicTypeAssertExpr{X: x, RType: rtype}
734 n.pos = pos
735 n.op = op
736 return n
737 }
738
739 func (n *DynamicTypeAssertExpr) SetOp(op Op) {
740 switch op {
741 default:
742 panic(n.no("SetOp " + op.String()))
743 case ODYNAMICDOTTYPE, ODYNAMICDOTTYPE2:
744 n.op = op
745 }
746 }
747
748
749
750 type UnaryExpr struct {
751 miniExpr
752 X Node
753 }
754
755 func NewUnaryExpr(pos src.XPos, op Op, x Node) *UnaryExpr {
756 n := &UnaryExpr{X: x}
757 n.pos = pos
758 n.SetOp(op)
759 return n
760 }
761
762 func (n *UnaryExpr) SetOp(op Op) {
763 switch op {
764 default:
765 panic(n.no("SetOp " + op.String()))
766 case OBITNOT, ONEG, ONOT, OPLUS, ORECV,
767 OCAP, OCLEAR, OCLOSE, OIMAG, OLEN, ONEW, OPANIC, OREAL,
768 OCHECKNIL, OCFUNC, OIDATA, OITAB, OSPTR,
769 OUNSAFESTRINGDATA, OUNSAFESLICEDATA:
770 n.op = op
771 }
772 }
773
774 func IsZero(n Node) bool {
775 switch n.Op() {
776 case ONIL:
777 return true
778
779 case OLITERAL:
780 switch u := n.Val(); u.Kind() {
781 case constant.String:
782 return constant.StringVal(u) == ""
783 case constant.Bool:
784 return !constant.BoolVal(u)
785 default:
786 return constant.Sign(u) == 0
787 }
788
789 case OARRAYLIT:
790 n := n.(*CompLitExpr)
791 for _, n1 := range n.List {
792 if n1.Op() == OKEY {
793 n1 = n1.(*KeyExpr).Value
794 }
795 if !IsZero(n1) {
796 return false
797 }
798 }
799 return true
800
801 case OSTRUCTLIT:
802 n := n.(*CompLitExpr)
803 for _, n1 := range n.List {
804 n1 := n1.(*StructKeyExpr)
805 if !IsZero(n1.Value) {
806 return false
807 }
808 }
809 return true
810 }
811
812 return false
813 }
814
815
816 func IsAddressable(n Node) bool {
817 switch n.Op() {
818 case OINDEX:
819 n := n.(*IndexExpr)
820 if n.X.Type() != nil && n.X.Type().IsArray() {
821 return IsAddressable(n.X)
822 }
823 if n.X.Type() != nil && n.X.Type().IsString() {
824 return false
825 }
826 fallthrough
827 case ODEREF, ODOTPTR:
828 return true
829
830 case ODOT:
831 n := n.(*SelectorExpr)
832 return IsAddressable(n.X)
833
834 case ONAME:
835 n := n.(*Name)
836 if n.Class == PFUNC {
837 return false
838 }
839 return true
840
841 case OLINKSYMOFFSET:
842 return true
843 }
844
845 return false
846 }
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866 func StaticValue(n Node) Node {
867 for {
868 switch n1 := n.(type) {
869 case *ConvExpr:
870 if n1.Op() == OCONVNOP {
871 n = n1.X
872 continue
873 }
874 case *InlinedCallExpr:
875 if n1.Op() == OINLCALL {
876 n = n1.SingleResult()
877 continue
878 }
879 case *ParenExpr:
880 n = n1.X
881 continue
882 }
883
884 n1 := staticValue1(n)
885 if n1 == nil {
886 return n
887 }
888 n = n1
889 }
890 }
891
892 func staticValue1(nn Node) Node {
893 if nn.Op() != ONAME {
894 return nil
895 }
896 n := nn.(*Name).Canonical()
897 if n.Class != PAUTO {
898 return nil
899 }
900
901 defn := n.Defn
902 if defn == nil {
903 return nil
904 }
905
906 var rhs Node
907 FindRHS:
908 switch defn.Op() {
909 case OAS:
910 defn := defn.(*AssignStmt)
911 rhs = defn.Y
912 case OAS2:
913 defn := defn.(*AssignListStmt)
914 for i, lhs := range defn.Lhs {
915 if lhs == n {
916 rhs = defn.Rhs[i]
917 break FindRHS
918 }
919 }
920 base.FatalfAt(defn.Pos(), "%v missing from LHS of %v", n, defn)
921 default:
922 return nil
923 }
924 if rhs == nil {
925 base.FatalfAt(defn.Pos(), "RHS is nil: %v", defn)
926 }
927
928 if Reassigned(n) {
929 return nil
930 }
931
932 return rhs
933 }
934
935
936
937
938
939
940
941
942
943 func Reassigned(name *Name) bool {
944 if name.Op() != ONAME {
945 base.Fatalf("reassigned %v", name)
946 }
947
948 if name.Curfn == nil {
949 return true
950 }
951
952 if name.Addrtaken() {
953 return true
954 }
955
956
957
958
959
960
961 isName := func(x Node) bool {
962 if x == nil {
963 return false
964 }
965 n, ok := OuterValue(x).(*Name)
966 return ok && n.Canonical() == name
967 }
968
969 var do func(n Node) bool
970 do = func(n Node) bool {
971 switch n.Op() {
972 case OAS:
973 n := n.(*AssignStmt)
974 if isName(n.X) && n != name.Defn {
975 return true
976 }
977 case OAS2, OAS2FUNC, OAS2MAPR, OAS2DOTTYPE, OAS2RECV, OSELRECV2:
978 n := n.(*AssignListStmt)
979 for _, p := range n.Lhs {
980 if isName(p) && n != name.Defn {
981 return true
982 }
983 }
984 case OASOP:
985 n := n.(*AssignOpStmt)
986 if isName(n.X) {
987 return true
988 }
989 case OADDR:
990 n := n.(*AddrExpr)
991 if isName(n.X) {
992 base.FatalfAt(n.Pos(), "%v not marked addrtaken", name)
993 }
994 case ORANGE:
995 n := n.(*RangeStmt)
996 if isName(n.Key) || isName(n.Value) {
997 return true
998 }
999 case OCLOSURE:
1000 n := n.(*ClosureExpr)
1001 if Any(n.Func, do) {
1002 return true
1003 }
1004 }
1005 return false
1006 }
1007 return Any(name.Curfn, do)
1008 }
1009
1010
1011 func StaticCalleeName(n Node) *Name {
1012 switch n.Op() {
1013 case OMETHEXPR:
1014 n := n.(*SelectorExpr)
1015 return MethodExprName(n)
1016 case ONAME:
1017 n := n.(*Name)
1018 if n.Class == PFUNC {
1019 return n
1020 }
1021 case OCLOSURE:
1022 return n.(*ClosureExpr).Func.Nname
1023 }
1024 return nil
1025 }
1026
1027
1028 var IsIntrinsicCall = func(*CallExpr) bool { return false }
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045 func SameSafeExpr(l Node, r Node) bool {
1046 for l.Op() == OCONVNOP {
1047 l = l.(*ConvExpr).X
1048 }
1049 for r.Op() == OCONVNOP {
1050 r = r.(*ConvExpr).X
1051 }
1052 if l.Op() != r.Op() || !types.Identical(l.Type(), r.Type()) {
1053 return false
1054 }
1055
1056 switch l.Op() {
1057 case ONAME:
1058 return l == r
1059
1060 case ODOT, ODOTPTR:
1061 l := l.(*SelectorExpr)
1062 r := r.(*SelectorExpr)
1063 return l.Sel != nil && r.Sel != nil && l.Sel == r.Sel && SameSafeExpr(l.X, r.X)
1064
1065 case ODEREF:
1066 l := l.(*StarExpr)
1067 r := r.(*StarExpr)
1068 return SameSafeExpr(l.X, r.X)
1069
1070 case ONOT, OBITNOT, OPLUS, ONEG:
1071 l := l.(*UnaryExpr)
1072 r := r.(*UnaryExpr)
1073 return SameSafeExpr(l.X, r.X)
1074
1075 case OCONV:
1076 l := l.(*ConvExpr)
1077 r := r.(*ConvExpr)
1078
1079
1080 return types.IsSimple[l.Type().Kind()] && SameSafeExpr(l.X, r.X)
1081
1082 case OINDEX, OINDEXMAP:
1083 l := l.(*IndexExpr)
1084 r := r.(*IndexExpr)
1085 return SameSafeExpr(l.X, r.X) && SameSafeExpr(l.Index, r.Index)
1086
1087 case OADD, OSUB, OOR, OXOR, OMUL, OLSH, ORSH, OAND, OANDNOT, ODIV, OMOD:
1088 l := l.(*BinaryExpr)
1089 r := r.(*BinaryExpr)
1090 return SameSafeExpr(l.X, r.X) && SameSafeExpr(l.Y, r.Y)
1091
1092 case OLITERAL:
1093 return constant.Compare(l.Val(), token.EQL, r.Val())
1094
1095 case ONIL:
1096 return true
1097 }
1098
1099 return false
1100 }
1101
1102
1103
1104
1105 func ShouldCheckPtr(fn *Func, level int) bool {
1106 return base.Debug.Checkptr >= level && fn.Pragma&NoCheckPtr == 0
1107 }
1108
1109
1110
1111 func ShouldAsanCheckPtr(fn *Func) bool {
1112 return base.Flag.ASan && fn.Pragma&NoCheckPtr == 0
1113 }
1114
1115
1116
1117 func IsReflectHeaderDataField(l Node) bool {
1118 if l.Type() != types.Types[types.TUINTPTR] {
1119 return false
1120 }
1121
1122 var tsym *types.Sym
1123 switch l.Op() {
1124 case ODOT:
1125 l := l.(*SelectorExpr)
1126 tsym = l.X.Type().Sym()
1127 case ODOTPTR:
1128 l := l.(*SelectorExpr)
1129 tsym = l.X.Type().Elem().Sym()
1130 default:
1131 return false
1132 }
1133
1134 if tsym == nil || l.Sym().Name != "Data" || tsym.Pkg.Path != "reflect" {
1135 return false
1136 }
1137 return tsym.Name == "SliceHeader" || tsym.Name == "StringHeader"
1138 }
1139
1140 func ParamNames(ft *types.Type) []Node {
1141 args := make([]Node, ft.NumParams())
1142 for i, f := range ft.Params() {
1143 args[i] = f.Nname.(*Name)
1144 }
1145 return args
1146 }
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156 func MethodSym(recv *types.Type, msym *types.Sym) *types.Sym {
1157 sym := MethodSymSuffix(recv, msym, "")
1158 sym.SetFunc(true)
1159 return sym
1160 }
1161
1162
1163
1164
1165 func MethodSymSuffix(recv *types.Type, msym *types.Sym, suffix string) *types.Sym {
1166 if msym.IsBlank() {
1167 base.Fatalf("blank method name")
1168 }
1169
1170 rsym := recv.Sym()
1171 if recv.IsPtr() {
1172 if rsym != nil {
1173 base.Fatalf("declared pointer receiver type: %v", recv)
1174 }
1175 rsym = recv.Elem().Sym()
1176 }
1177
1178
1179
1180
1181 rpkg := Pkgs.Go
1182 if rsym != nil {
1183 rpkg = rsym.Pkg
1184 }
1185
1186 var b bytes.Buffer
1187 if recv.IsPtr() {
1188
1189
1190 fmt.Fprintf(&b, "(%-S)", recv)
1191 } else {
1192 fmt.Fprintf(&b, "%-S", recv)
1193 }
1194
1195
1196
1197
1198
1199 if !types.IsExported(msym.Name) && msym.Pkg != rpkg {
1200 b.WriteString(".")
1201 b.WriteString(msym.Pkg.Prefix)
1202 }
1203
1204 b.WriteString(".")
1205 b.WriteString(msym.Name)
1206 b.WriteString(suffix)
1207 return rpkg.LookupBytes(b.Bytes())
1208 }
1209
1210
1211
1212
1213
1214 func LookupMethodSelector(pkg *types.Pkg, name string) (typ, meth *types.Sym, err error) {
1215 typeName, methName := splitType(name)
1216 if typeName == "" {
1217 return nil, nil, fmt.Errorf("%s doesn't contain type split", name)
1218 }
1219
1220 if len(typeName) > 3 && typeName[:2] == "(*" && typeName[len(typeName)-1] == ')' {
1221
1222
1223 typeName = typeName[2 : len(typeName)-1]
1224 }
1225
1226 typ = pkg.Lookup(typeName)
1227 meth = pkg.Selector(methName)
1228 return typ, meth, nil
1229 }
1230
1231
1232
1233
1234
1235
1236 func splitType(name string) (typ, fn string) {
1237
1238
1239
1240 bracket := 0
1241 for i, r := range name {
1242 if r == '.' && bracket == 0 {
1243 return name[:i], name[i+1:]
1244 }
1245 if r == '[' {
1246 bracket++
1247 }
1248 if r == ']' {
1249 bracket--
1250 }
1251 }
1252 return "", name
1253 }
1254
1255
1256
1257
1258 func MethodExprName(n Node) *Name {
1259 name, _ := MethodExprFunc(n).Nname.(*Name)
1260 return name
1261 }
1262
1263
1264 func MethodExprFunc(n Node) *types.Field {
1265 switch n.Op() {
1266 case ODOTMETH, OMETHEXPR, OMETHVALUE:
1267 return n.(*SelectorExpr).Selection
1268 }
1269 base.Fatalf("unexpected node: %v (%v)", n, n.Op())
1270 panic("unreachable")
1271 }
1272
View as plain text