From d8ad35efe20c008e71b2359a09aee0662ede5eb9 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Tue, 4 Jan 2022 15:28:37 +0100 Subject: prog: support prunning recursion in ForeachType --- prog/types.go | 12 ++++++++++-- 1 file 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 { -- cgit mrf-deployment