...
1
2
3
4
5 package escape
6
7 import (
8 "cmd/compile/internal/base"
9 "cmd/compile/internal/ir"
10 )
11
12
13
14 func (e *escape) addr(n ir.Node) hole {
15 if n == nil || ir.IsBlank(n) {
16
17 return e.discardHole()
18 }
19
20 k := e.heapHole()
21
22 switch n.Op() {
23 default:
24 base.Fatalf("unexpected addr: %v", n)
25 case ir.ONAME:
26 n := n.(*ir.Name)
27 if n.Class == ir.PEXTERN {
28 break
29 }
30 k = e.oldLoc(n).asHole()
31 case ir.OLINKSYMOFFSET:
32 break
33 case ir.ODOT:
34 n := n.(*ir.SelectorExpr)
35 k = e.addr(n.X)
36 case ir.OINDEX:
37 n := n.(*ir.IndexExpr)
38 e.discard(n.Index)
39 if n.X.Type().IsArray() {
40 k = e.addr(n.X)
41 } else {
42 e.mutate(n.X)
43 }
44 case ir.ODEREF:
45 n := n.(*ir.StarExpr)
46 e.mutate(n.X)
47 case ir.ODOTPTR:
48 n := n.(*ir.SelectorExpr)
49 e.mutate(n.X)
50 case ir.OINDEXMAP:
51 n := n.(*ir.IndexExpr)
52 e.discard(n.X)
53
54
55 e.assignHeap(n.Index, "key of map put", n)
56 }
57
58 return k
59 }
60
61 func (e *escape) mutate(n ir.Node) {
62 e.expr(e.mutatorHole(), n)
63 }
64
65 func (e *escape) addrs(l ir.Nodes) []hole {
66 var ks []hole
67 for _, n := range l {
68 ks = append(ks, e.addr(n))
69 }
70 return ks
71 }
72
73 func (e *escape) assignHeap(src ir.Node, why string, where ir.Node) {
74 e.expr(e.heapHole().note(where, why), src)
75 }
76
77
78 func (e *escape) assignList(dsts, srcs []ir.Node, why string, where ir.Node) {
79 ks := e.addrs(dsts)
80 for i, k := range ks {
81 var src ir.Node
82 if i < len(srcs) {
83 src = srcs[i]
84 }
85
86 if dst := dsts[i]; dst != nil {
87
88
89 if dst.Op() == ir.ODOTPTR && ir.IsReflectHeaderDataField(dst) {
90 e.unsafeValue(e.heapHole().note(where, why), src)
91 continue
92 }
93
94
95 if src != nil && isSelfAssign(dst, src) {
96 if base.Flag.LowerM != 0 {
97 base.WarnfAt(where.Pos(), "%v ignoring self-assignment in %v", e.curfn, where)
98 }
99 k = e.discardHole()
100 }
101 }
102
103 e.expr(k.note(where, why), src)
104 }
105
106 e.reassigned(ks, where)
107 }
108
109
110
111
112 func (e *escape) reassigned(ks []hole, where ir.Node) {
113 if as, ok := where.(*ir.AssignStmt); ok && as.Op() == ir.OAS && as.Y == nil {
114 if dst, ok := as.X.(*ir.Name); ok && dst.Op() == ir.ONAME && dst.Defn == nil {
115
116
117
118 return
119 }
120 }
121
122 for _, k := range ks {
123 loc := k.dst
124
125 if n, ok := loc.n.(*ir.Name); ok && n.Defn == where && where.Op() != ir.ORANGE {
126 continue
127 }
128 loc.reassigned = true
129 }
130 }
131
View as plain text