1
2
3
4
5 package field
6
7 import (
8 "testing"
9 "testing/quick"
10 )
11
12 func checkAliasingOneArg(f func(v, x *Element) *Element) func(v, x Element) bool {
13 return func(v, x Element) bool {
14 x1, v1 := x, x
15
16
17 if out := f(&v, &x); out != &v && isInBounds(out) {
18 return false
19 }
20
21
22 if out := f(&v1, &v1); out != &v1 || v1 != v {
23 return false
24 }
25
26
27 return x == x1
28 }
29 }
30
31 func checkAliasingTwoArgs(f func(v, x, y *Element) *Element) func(v, x, y Element) bool {
32 return func(v, x, y Element) bool {
33 x1, y1, v1 := x, y, Element{}
34
35
36 if out := f(&v, &x, &y); out != &v && isInBounds(out) {
37 return false
38 }
39
40
41 v1 = x
42 if out := f(&v1, &v1, &y); out != &v1 || v1 != v {
43 return false
44 }
45
46 v1 = y
47 if out := f(&v1, &x, &v1); out != &v1 || v1 != v {
48 return false
49 }
50
51
52 if out := f(&v, &x, &x); out != &v {
53 return false
54 }
55
56
57 v1 = x
58 if out := f(&v1, &v1, &x); out != &v1 || v1 != v {
59 return false
60 }
61
62 v1 = x
63 if out := f(&v1, &x, &v1); out != &v1 || v1 != v {
64 return false
65 }
66
67 v1 = x
68 if out := f(&v1, &v1, &v1); out != &v1 || v1 != v {
69 return false
70 }
71
72
73 return x == x1 && y == y1
74 }
75 }
76
77
78
79
80
81
82
83
84
85
86
87 func TestAliasing(t *testing.T) {
88 type target struct {
89 name string
90 oneArgF func(v, x *Element) *Element
91 twoArgsF func(v, x, y *Element) *Element
92 }
93 for _, tt := range []target{
94 {name: "Absolute", oneArgF: (*Element).Absolute},
95 {name: "Invert", oneArgF: (*Element).Invert},
96 {name: "Negate", oneArgF: (*Element).Negate},
97 {name: "Set", oneArgF: (*Element).Set},
98 {name: "Square", oneArgF: (*Element).Square},
99 {name: "Multiply", twoArgsF: (*Element).Multiply},
100 {name: "Add", twoArgsF: (*Element).Add},
101 {name: "Subtract", twoArgsF: (*Element).Subtract},
102 {
103 name: "Select0",
104 twoArgsF: func(v, x, y *Element) *Element {
105 return (*Element).Select(v, x, y, 0)
106 },
107 },
108 {
109 name: "Select1",
110 twoArgsF: func(v, x, y *Element) *Element {
111 return (*Element).Select(v, x, y, 1)
112 },
113 },
114 } {
115 var err error
116 switch {
117 case tt.oneArgF != nil:
118 err = quick.Check(checkAliasingOneArg(tt.oneArgF), &quick.Config{MaxCountScale: 1 << 8})
119 case tt.twoArgsF != nil:
120 err = quick.Check(checkAliasingTwoArgs(tt.twoArgsF), &quick.Config{MaxCountScale: 1 << 8})
121 }
122 if err != nil {
123 t.Errorf("%v: %v", tt.name, err)
124 }
125 }
126 }
127
View as plain text