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