Source file
test/fixedbugs/issue9604b.go
1
2
3
4
5
6
7
8
9
10 package main
11
12 import (
13 "fmt"
14 "math/big"
15 "unsafe"
16 )
17
18 var one = big.NewInt(1)
19
20 type _type struct {
21 name string
22 bits uint
23 signed bool
24 }
25
26
27 func (t *_type) testvalues() []*big.Int {
28 var a []*big.Int
29
30 a = append(a, big.NewInt(0))
31 a = append(a, big.NewInt(1))
32 a = append(a, big.NewInt(2))
33 if t.signed {
34 a = append(a, big.NewInt(-1))
35 a = append(a, big.NewInt(-2))
36 r := big.NewInt(1)
37 a = append(a, r.Lsh(r, t.bits-1).Sub(r, big.NewInt(1)))
38 r = big.NewInt(1)
39 a = append(a, r.Lsh(r, t.bits-1).Sub(r, big.NewInt(2)))
40 r = big.NewInt(1)
41 a = append(a, r.Lsh(r, t.bits-1).Neg(r))
42 r = big.NewInt(1)
43 a = append(a, r.Lsh(r, t.bits-1).Neg(r).Add(r, big.NewInt(1)))
44 } else {
45 r := big.NewInt(1)
46 a = append(a, r.Lsh(r, t.bits).Sub(r, big.NewInt(1)))
47 r = big.NewInt(1)
48 a = append(a, r.Lsh(r, t.bits).Sub(r, big.NewInt(2)))
49 }
50 return a
51 }
52
53
54 func (t *_type) trunc(x *big.Int) *big.Int {
55 r := new(big.Int)
56 m := new(big.Int)
57 m.Lsh(one, t.bits)
58 m.Sub(m, one)
59 r.And(x, m)
60 if t.signed && r.Bit(int(t.bits)-1) == 1 {
61 m.Neg(one)
62 m.Lsh(m, t.bits)
63 r.Or(r, m)
64 }
65 return r
66 }
67
68 var types = []_type{
69 _type{"byte", 8, false},
70 _type{"int8", 8, true},
71 _type{"uint8", 8, false},
72 _type{"rune", 32, true},
73 _type{"int16", 16, true},
74 _type{"uint16", 16, false},
75 _type{"int32", 32, true},
76 _type{"uint32", 32, false},
77 _type{"int64", 64, true},
78 _type{"uint64", 64, false},
79 _type{"int", 8 * uint(unsafe.Sizeof(int(0))), true},
80 _type{"uint", 8 * uint(unsafe.Sizeof(uint(0))), false},
81 _type{"uintptr", 8 * uint(unsafe.Sizeof((*byte)(nil))), false},
82 }
83
84 type binop struct {
85 name string
86 eval func(x, y *big.Int) *big.Int
87 }
88
89 var binops = []binop{
90 binop{"+", func(x, y *big.Int) *big.Int { return new(big.Int).Add(x, y) }},
91 binop{"-", func(x, y *big.Int) *big.Int { return new(big.Int).Sub(x, y) }},
92 binop{"*", func(x, y *big.Int) *big.Int { return new(big.Int).Mul(x, y) }},
93 binop{"/", func(x, y *big.Int) *big.Int { return new(big.Int).Quo(x, y) }},
94 binop{"%", func(x, y *big.Int) *big.Int { return new(big.Int).Rem(x, y) }},
95 binop{"&", func(x, y *big.Int) *big.Int { return new(big.Int).And(x, y) }},
96 binop{"|", func(x, y *big.Int) *big.Int { return new(big.Int).Or(x, y) }},
97 binop{"^", func(x, y *big.Int) *big.Int { return new(big.Int).Xor(x, y) }},
98 binop{"&^", func(x, y *big.Int) *big.Int { return new(big.Int).AndNot(x, y) }},
99 }
100
101 type unop struct {
102 name string
103 eval func(x *big.Int) *big.Int
104 }
105
106 var unops = []unop{
107 unop{"+", func(x *big.Int) *big.Int { return new(big.Int).Set(x) }},
108 unop{"-", func(x *big.Int) *big.Int { return new(big.Int).Neg(x) }},
109 unop{"^", func(x *big.Int) *big.Int { return new(big.Int).Not(x) }},
110 }
111
112 type shiftop struct {
113 name string
114 eval func(x *big.Int, i uint) *big.Int
115 }
116
117 var shiftops = []shiftop{
118 shiftop{"<<", func(x *big.Int, i uint) *big.Int { return new(big.Int).Lsh(x, i) }},
119 shiftop{">>", func(x *big.Int, i uint) *big.Int { return new(big.Int).Rsh(x, i) }},
120 }
121
122
123 func valname(n *big.Int) string {
124 s := fmt.Sprintf("%d", n)
125 if s[0] == '-' {
126 s = "neg" + s[1:]
127 }
128 return s
129 }
130
131 func main() {
132 fmt.Println("package main")
133
134
135
136 for _, t := range types {
137 for _, n := range t.testvalues() {
138 fmt.Printf("var %s_%s %s = %d\n", t.name, valname(n), t.name, n)
139 }
140 }
141
142 fmt.Println("func main() {")
143
144 for _, t := range types {
145
146 for _, op := range binops {
147 for _, x := range t.testvalues() {
148 for _, y := range t.testvalues() {
149 if (op.name == "/" || op.name == "%") && y.Sign() == 0 {
150 continue
151 }
152 r := t.trunc(op.eval(x, y))
153 eqn := fmt.Sprintf("%s_%s %s %s_%s != %d", t.name, valname(x), op.name, t.name, valname(y), r)
154 fmt.Printf("\tif %s { println(\"bad: %s\") }\n", eqn, eqn)
155 }
156 }
157 }
158
159 for _, op := range unops {
160 for _, x := range t.testvalues() {
161 r := t.trunc(op.eval(x))
162 eqn := fmt.Sprintf("%s %s_%s != %d", op.name, t.name, valname(x), r)
163 fmt.Printf("\tif %s { println(\"bad: %s\") }\n", eqn, eqn)
164 }
165 }
166
167 for _, op := range shiftops {
168 for _, x := range t.testvalues() {
169
170 for _, i := range []uint{0, 1, t.bits - 2, t.bits - 1, t.bits, t.bits + 1} {
171 r := t.trunc(op.eval(x, i))
172 eqn := fmt.Sprintf("%s_%s %s %d != %d", t.name, valname(x), op.name, i, r)
173 fmt.Printf("\tif %s { println(\"bad: %s\") }\n", eqn, eqn)
174 }
175 }
176 }
177 }
178
179 fmt.Println("}")
180 }
181
View as plain text