aboutsummaryrefslogtreecommitdiffstats
path: root/prog/mutation.go
diff options
context:
space:
mode:
authorVeronica Radu <veronicaradu@google.com>2019-08-07 18:00:46 +0200
committerDmitry Vyukov <dvyukov@google.com>2019-08-09 15:02:02 +0200
commitaff9e255cd708709adef545d1f932020ee5c0978 (patch)
tree353468cb149a587e747cfc702003946abd5130a2 /prog/mutation.go
parente5701ed16c822ef5a4abc4224b44c36b3489aca3 (diff)
prog: add special mutation for binary flags
Diffstat (limited to 'prog/mutation.go')
-rw-r--r--prog/mutation.go26
1 files changed, 25 insertions, 1 deletions
diff --git a/prog/mutation.go b/prog/mutation.go
index dbb605041..a3ab17637 100644
--- a/prog/mutation.go
+++ b/prog/mutation.go
@@ -234,7 +234,31 @@ func (t *IntType) mutate(r *randGen, s *state, arg Arg, ctx ArgCtx) (calls []*Ca
}
func (t *FlagsType) mutate(r *randGen, s *state, arg Arg, ctx ArgCtx) (calls []*Call, retry, preserve bool) {
- return mutateInt(r, s, arg)
+ a := arg.(*ConstArg)
+
+ for oldVal := a.Val; oldVal == a.Val; {
+ // Generate a new value.
+ if r.nOutOf(1, 5) {
+ a.Val = r.flags(t.Vals, t.BitMask, 0)
+ continue
+ }
+
+ if !t.BitMask || (t.BitMask && r.nOutOf(1, 4)) {
+ a.Val = r.flags(t.Vals, t.BitMask, a.Val)
+ continue
+ }
+
+ for stop := false; !stop; stop = r.oneOf(3) {
+ idx := r.rand(len(t.Vals))
+ if r.bin() {
+ a.Val |= 1 << t.Vals[idx]
+ } else {
+ a.Val &= ^(1 << t.Vals[idx])
+ }
+ }
+ }
+
+ return
}
func (t *LenType) mutate(r *randGen, s *state, arg Arg, ctx ArgCtx) (calls []*Call, retry, preserve bool) {