aboutsummaryrefslogtreecommitdiffstats
path: root/prog/rand.go
diff options
context:
space:
mode:
authorVeronica Radu <veronicaradu@google.com>2019-09-11 18:20:17 +0200
committerDmitry Vyukov <dvyukov@google.com>2019-09-23 15:33:19 +0200
commitbf7e28925b8894ca13f803f66d16cf2b0ae12430 (patch)
tree5e25e384f1b97ff2f3fda580dd2ac2fe6fb43d91 /prog/rand.go
parentd96e88f3207d7ac7ad65e13b896f702ad04c46f7 (diff)
prog: use type size when generating/mutating ints
Update #1381
Diffstat (limited to 'prog/rand.go')
-rw-r--r--prog/rand.go70
1 files changed, 49 insertions, 21 deletions
diff --git a/prog/rand.go b/prog/rand.go
index cbfc960a8..3306ced66 100644
--- a/prog/rand.go
+++ b/prog/rand.go
@@ -55,24 +55,44 @@ func (r *randGen) rand64() uint64 {
return v
}
-// Some potentially interesting integers.
-var specialInts = []uint64{
- 0, 1, 31, 32, 63, 64, 127, 128,
- 129, 255, 256, 257, 511, 512,
- 1023, 1024, 1025, 2047, 2048, 4095, 4096,
- (1 << 15) - 1, (1 << 15), (1 << 15) + 1,
- (1 << 16) - 1, (1 << 16), (1 << 16) + 1,
- (1 << 31) - 1, (1 << 31), (1 << 31) + 1,
- (1 << 32) - 1, (1 << 32), (1 << 32) + 1,
-}
-
-func (r *randGen) randInt() uint64 {
+var (
+ // Some potentially interesting integers.
+ specialInts = []uint64{
+ 0, 1, 31, 32, 63, 64, 127, 128,
+ 129, 255, 256, 257, 511, 512,
+ 1023, 1024, 1025, 2047, 2048, 4095, 4096,
+ (1 << 15) - 1, (1 << 15), (1 << 15) + 1,
+ (1 << 16) - 1, (1 << 16), (1 << 16) + 1,
+ (1 << 31) - 1, (1 << 31), (1 << 31) + 1,
+ (1 << 32) - 1, (1 << 32), (1 << 32) + 1,
+ }
+ // The indexes (exclusive) for the maximum specialInts values that fit in 1, 2, ... 8 bytes.
+ specialIntIndex [9]int
+)
+
+func init() {
+ sort.Slice(specialInts, func(i, j int) bool {
+ return specialInts[i] < specialInts[j]
+ })
+ for i := range specialIntIndex {
+ bitSize := uint64(8 * i)
+ specialIntIndex[i] = sort.Search(len(specialInts), func(i int) bool {
+ return specialInts[i]>>bitSize != 0
+ })
+ }
+}
+
+func (r *randGen) randInt64() uint64 {
+ return r.randInt(64)
+}
+
+func (r *randGen) randInt(bits uint64) uint64 {
v := r.rand64()
switch {
case r.nOutOf(100, 182):
v %= 10
- case r.nOutOf(50, 82):
- v = specialInts[r.Intn(len(specialInts))]
+ case bits >= 8 && r.nOutOf(50, 82):
+ v = specialInts[r.Intn(specialIntIndex[bits/8])]
case r.nOutOf(10, 32):
v %= 256
case r.nOutOf(10, 22):
@@ -87,14 +107,21 @@ func (r *randGen) randInt() uint64 {
case r.nOutOf(5, 7):
v = uint64(-int64(v))
default:
- v <<= uint(r.Intn(63))
+ v <<= uint(r.Intn(int(bits)))
}
- return v
+ return truncateToBitSize(v, bits)
+}
+
+func truncateToBitSize(v, bitSize uint64) uint64 {
+ if bitSize == 0 || bitSize > 64 {
+ panic(fmt.Sprintf("invalid bitSize value: %d", bitSize))
+ }
+ return v & uint64(1<<bitSize-1)
}
-func (r *randGen) randRangeInt(begin uint64, end uint64) uint64 {
+func (r *randGen) randRangeInt(begin, end, bitSize uint64) uint64 {
if r.oneOf(100) {
- return r.randInt()
+ return r.randInt(bitSize)
}
return begin + (r.Uint64() % (end - begin + 1))
}
@@ -710,7 +737,8 @@ func (a *ConstType) generate(r *randGen, s *state) (arg Arg, calls []*Call) {
}
func (a *IntType) generate(r *randGen, s *state) (arg Arg, calls []*Call) {
- v := r.randInt()
+ bits := a.TypeBitSize()
+ v := r.randInt(bits)
switch a.Kind {
case IntFileoff:
switch {
@@ -719,10 +747,10 @@ func (a *IntType) generate(r *randGen, s *state) (arg Arg, calls []*Call) {
case r.nOutOf(10, 11):
v = r.rand(100)
default:
- v = r.randInt()
+ v = r.randInt(bits)
}
case IntRange:
- v = r.randRangeInt(a.RangeBegin, a.RangeEnd)
+ v = r.randRangeInt(a.RangeBegin, a.RangeEnd, bits)
}
return MakeConstArg(a, v), nil
}