aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2022-01-04 15:28:37 +0100
committerDmitry Vyukov <dvyukov@google.com>2022-01-11 16:30:08 +0100
commitd8ad35efe20c008e71b2359a09aee0662ede5eb9 (patch)
tree57b89e80723261a1f5eea67ac6f5923a5be8acfb
parent983508d80442a85b78118e6c6a03d5ae4897e4df (diff)
prog: support prunning recursion in ForeachType
-rw-r--r--prog/types.go12
1 files changed, 10 insertions, 2 deletions
diff --git a/prog/types.go b/prog/types.go
index 110ddabeb..cca6f1d6c 100644
--- a/prog/types.go
+++ b/prog/types.go
@@ -676,6 +676,7 @@ type TypeCtx struct {
Meta *Syscall
Dir Dir
Ptr *Type
+ Stop bool // If set by the callback, subtypes of this type are not visited.
}
func ForeachType(syscalls []*Syscall, f func(t Type, ctx *TypeCtx)) {
@@ -701,8 +702,12 @@ func foreachTypeImpl(meta *Syscall, preorder bool, f func(t Type, ctx *TypeCtx))
seen := make(map[Type]bool)
var rec func(*Type, Dir)
rec = func(ptr *Type, dir Dir) {
+ ctx := &TypeCtx{Meta: meta, Dir: dir, Ptr: ptr}
if preorder {
- f(*ptr, &TypeCtx{Meta: meta, Dir: dir, Ptr: ptr})
+ f(*ptr, ctx)
+ if ctx.Stop {
+ return
+ }
}
switch a := (*ptr).(type) {
case *PtrType:
@@ -733,7 +738,10 @@ func foreachTypeImpl(meta *Syscall, preorder bool, f func(t Type, ctx *TypeCtx))
panic("unknown type")
}
if !preorder {
- f(*ptr, &TypeCtx{Meta: meta, Dir: dir, Ptr: ptr})
+ f(*ptr, ctx)
+ if ctx.Stop {
+ panic("Stop is set in post-order iteration")
+ }
}
}
for i := range meta.Args {