diff options
Diffstat (limited to 'prog/analysis.go')
| -rw-r--r-- | prog/analysis.go | 43 |
1 files changed, 11 insertions, 32 deletions
diff --git a/prog/analysis.go b/prog/analysis.go index 0c4102a47..2d691934a 100644 --- a/prog/analysis.go +++ b/prog/analysis.go @@ -112,12 +112,23 @@ func foreachArgImpl(arg Arg, ctx ArgCtx, f func(Arg, *ArgCtx)) { if _, ok := a.Type().(*StructType); ok { ctx.Parent = &a.Inner } + var totalSize uint64 for _, arg1 := range a.Inner { foreachArgImpl(arg1, ctx, f) + if !arg1.Type().BitfieldMiddle() { + size := arg1.Size() + ctx.Offset += size + totalSize += size + } + } + if totalSize > a.Size() { + panic(fmt.Sprintf("bad group arg size %v, should be <= %v for %+v", + totalSize, a.Size(), a)) } case *PointerArg: if a.Res != nil { ctx.Base = a + ctx.Offset = 0 foreachArgImpl(a.Res, ctx, f) } case *UnionArg: @@ -125,38 +136,6 @@ func foreachArgImpl(arg Arg, ctx ArgCtx, f func(Arg, *ArgCtx)) { } } -func foreachSubargOffset(arg Arg, f func(arg Arg, offset uint64)) { - var rec func(Arg, uint64) uint64 - rec = func(arg1 Arg, offset uint64) uint64 { - switch a := arg1.(type) { - case *GroupArg: - f(arg1, offset) - var totalSize uint64 - for _, arg2 := range a.Inner { - size := rec(arg2, offset) - if !arg2.Type().BitfieldMiddle() { - offset += size - totalSize += size - } - } - if totalSize > arg1.Size() { - panic(fmt.Sprintf("bad group arg size %v, should be <= %v for %+v", totalSize, arg1.Size(), arg1)) - } - case *UnionArg: - f(arg1, offset) - size := rec(a.Option, offset) - offset += size - if size > arg1.Size() { - panic(fmt.Sprintf("bad union arg size %v, should be <= %v for arg %+v with type %+v", size, arg1.Size(), arg1, arg1.Type())) - } - default: - f(arg1, offset) - } - return arg1.Size() - } - rec(arg, 0) -} - // TODO(dvyukov): combine RequiresBitmasks and RequiresChecksums into a single function // to not walk the tree twice. They are always used together anyway. func RequiresBitmasks(p *Prog) bool { |
