Source file
test/fixedbugs/issue46304.go
1
2
3
4
5
6
7
8
9
10 package main
11
12 type Op struct {
13 tag string
14 _x []string
15 _q [20]uint64
16 plist []P
17 }
18
19 type P struct {
20 tag string
21 _x [10]uint64
22 b bool
23 }
24
25 type M int
26
27
28 func (w *M) walkP(p *P) *P {
29 np := &P{}
30 *np = *p
31 np.tag += "new"
32 return np
33 }
34
35 func (w *M) walkOp(op *Op) *Op {
36 if op == nil {
37 return nil
38 }
39
40 orig := op
41 cloned := false
42 clone := func() {
43 if !cloned {
44 cloned = true
45 op = &Op{}
46 *op = *orig
47 }
48 }
49
50 pCloned := false
51 for i := range op.plist {
52 if s := w.walkP(&op.plist[i]); s != &op.plist[i] {
53 if !pCloned {
54 pCloned = true
55 clone()
56 op.plist = make([]P, len(orig.plist))
57 copy(op.plist, orig.plist)
58 }
59 op.plist[i] = *s
60 }
61 }
62
63 return op
64 }
65
66 func main() {
67 var ww M
68 w := &ww
69 p1 := P{tag: "a"}
70 p1._x[1] = 9
71 o := Op{tag: "old", plist: []P{p1}}
72 no := w.walkOp(&o)
73 if no.plist[0].tag != "anew" {
74 panic("bad")
75 }
76 }
77
View as plain text