diff options
| author | Veronica Radu <veronicaradu@google.com> | 2019-09-11 18:20:17 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2019-09-23 15:33:19 +0200 |
| commit | bf7e28925b8894ca13f803f66d16cf2b0ae12430 (patch) | |
| tree | 5e25e384f1b97ff2f3fda580dd2ac2fe6fb43d91 /prog/rand.go | |
| parent | d96e88f3207d7ac7ad65e13b896f702ad04c46f7 (diff) | |
prog: use type size when generating/mutating ints
Update #1381
Diffstat (limited to 'prog/rand.go')
| -rw-r--r-- | prog/rand.go | 70 |
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 } |
