aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--prog/encoding.go36
-rw-r--r--prog/minimization.go6
-rw-r--r--prog/prog.go145
-rw-r--r--prog/prog_test.go4
-rw-r--r--prog/rand.go6
-rw-r--r--prog/types.go179
-rw-r--r--prog/validation.go15
7 files changed, 217 insertions, 174 deletions
diff --git a/prog/encoding.go b/prog/encoding.go
index f8866b573..1bdff4c6d 100644
--- a/prog/encoding.go
+++ b/prog/encoding.go
@@ -95,7 +95,7 @@ func (a *PointerArg) serialize(ctx *serializer) {
}
target := ctx.target
ctx.printf("&%v", target.serializeAddr(a))
- if a.Res != nil && target.isDefaultArg(a.Res) && !target.isAnyPtr(a.Type()) {
+ if a.Res != nil && isDefault(a.Res) && !target.isAnyPtr(a.Type()) {
return
}
ctx.printf("=")
@@ -135,7 +135,7 @@ func (a *GroupArg) serialize(ctx *serializer) {
lastNonDefault := len(a.Inner) - 1
if a.fixedInnerSize() {
for ; lastNonDefault >= 0; lastNonDefault-- {
- if !ctx.target.isDefaultArg(a.Inner[lastNonDefault]) {
+ if !isDefault(a.Inner[lastNonDefault]) {
break
}
}
@@ -155,7 +155,7 @@ func (a *GroupArg) serialize(ctx *serializer) {
func (a *UnionArg) serialize(ctx *serializer) {
ctx.printf("@%v", a.Option.Type().FieldName())
- if ctx.target.isDefaultArg(a.Option) {
+ if isDefault(a.Option) {
return
}
ctx.printf("=")
@@ -245,7 +245,7 @@ func (target *Target) Deserialize(data []byte) (prog *Prog, err error) {
c.Comment = strings.TrimSpace(p.s[p.i+1:])
}
for i := len(c.Args); i < len(meta.Args); i++ {
- c.Args = append(c.Args, target.defaultArg(meta.Args[i]))
+ c.Args = append(c.Args, meta.Args[i].makeDefaultArg())
}
if len(c.Args) != len(meta.Args) {
return nil, fmt.Errorf("wrong call arg count: %v, want %v", len(c.Args), len(meta.Args))
@@ -284,7 +284,7 @@ func (target *Target) parseArg(typ Type, p *parser, vars map[string]*ResultArg)
}
if arg == nil {
if typ != nil {
- arg = target.defaultArg(typ)
+ arg = typ.makeDefaultArg()
} else if r != "" {
return nil, fmt.Errorf("named nil argument")
}
@@ -340,10 +340,10 @@ func (target *Target) parseArgInt(typ Type, p *parser) (Arg, error) {
if typ.Optional() {
return MakeNullPointerArg(typ), nil
}
- return target.defaultArg(typ), nil
+ return typ.makeDefaultArg(), nil
default:
eatExcessive(p, true)
- return target.defaultArg(typ), nil
+ return typ.makeDefaultArg(), nil
}
}
@@ -370,7 +370,7 @@ func (target *Target) parseArgRes(typ Type, p *parser, vars map[string]*ResultAr
}
v := vars[id]
if v == nil {
- return target.defaultArg(typ), nil
+ return typ.makeDefaultArg(), nil
}
arg := MakeResultArg(typ, v, 0)
arg.OpDiv = div
@@ -386,7 +386,7 @@ func (target *Target) parseArgAddr(typ Type, p *parser, vars map[string]*ResultA
case *VmaType:
default:
eatExcessive(p, true)
- return target.defaultArg(typ), nil
+ return typ.makeDefaultArg(), nil
}
p.Parse('&')
addr, vmaSize, err := target.parseAddr(p)
@@ -413,7 +413,7 @@ func (target *Target) parseArgAddr(typ Type, p *parser, vars map[string]*ResultA
return MakeVmaPointerArg(typ, addr, vmaSize), nil
}
if inner == nil {
- inner = target.defaultArg(typ1)
+ inner = typ1.makeDefaultArg()
}
return MakePointerArg(typ, addr, inner), nil
}
@@ -421,7 +421,7 @@ func (target *Target) parseArgAddr(typ Type, p *parser, vars map[string]*ResultA
func (target *Target) parseArgString(typ Type, p *parser) (Arg, error) {
if _, ok := typ.(*BufferType); !ok {
eatExcessive(p, true)
- return target.defaultArg(typ), nil
+ return typ.makeDefaultArg(), nil
}
data, err := deserializeData(p)
if err != nil {
@@ -457,7 +457,7 @@ func (target *Target) parseArgStruct(typ Type, p *parser, vars map[string]*Resul
if !ok {
eatExcessive(p, false)
p.Parse('}')
- return target.defaultArg(typ), nil
+ return typ.makeDefaultArg(), nil
}
var inner []Arg
for i := 0; p.Char() != '}'; i++ {
@@ -481,7 +481,7 @@ func (target *Target) parseArgStruct(typ Type, p *parser, vars map[string]*Resul
}
p.Parse('}')
for len(inner) < len(t1.Fields) {
- inner = append(inner, target.defaultArg(t1.Fields[len(inner)]))
+ inner = append(inner, t1.Fields[len(inner)].makeDefaultArg())
}
return MakeGroupArg(typ, inner), nil
}
@@ -492,7 +492,7 @@ func (target *Target) parseArgArray(typ Type, p *parser, vars map[string]*Result
if !ok {
eatExcessive(p, false)
p.Parse(']')
- return target.defaultArg(typ), nil
+ return typ.makeDefaultArg(), nil
}
var inner []Arg
for i := 0; p.Char() != ']'; i++ {
@@ -508,7 +508,7 @@ func (target *Target) parseArgArray(typ Type, p *parser, vars map[string]*Result
p.Parse(']')
if t1.Kind == ArrayRangeLen && t1.RangeBegin == t1.RangeEnd {
for uint64(len(inner)) < t1.RangeBegin {
- inner = append(inner, target.defaultArg(t1.Type))
+ inner = append(inner, t1.Type.makeDefaultArg())
}
inner = inner[:t1.RangeBegin]
}
@@ -519,7 +519,7 @@ func (target *Target) parseArgUnion(typ Type, p *parser, vars map[string]*Result
t1, ok := typ.(*UnionType)
if !ok {
eatExcessive(p, true)
- return target.defaultArg(typ), nil
+ return typ.makeDefaultArg(), nil
}
p.Parse('@')
name := p.Ident()
@@ -532,7 +532,7 @@ func (target *Target) parseArgUnion(typ Type, p *parser, vars map[string]*Result
}
if optType == nil {
eatExcessive(p, true)
- return target.defaultArg(typ), nil
+ return typ.makeDefaultArg(), nil
}
var opt Arg
if p.Char() == '=' {
@@ -543,7 +543,7 @@ func (target *Target) parseArgUnion(typ Type, p *parser, vars map[string]*Result
return nil, err
}
} else {
- opt = target.defaultArg(optType)
+ opt = optType.makeDefaultArg()
}
return MakeUnionArg(typ, opt), nil
}
diff --git a/prog/minimization.go b/prog/minimization.go
index 1943ef4ea..021d8e2ea 100644
--- a/prog/minimization.go
+++ b/prog/minimization.go
@@ -178,12 +178,12 @@ func minimizeInt(ctx *minimizeArgsCtx, arg Arg, path string) bool {
return false
}
a := arg.(*ConstArg)
- def := arg.Type().Default()
- if a.Val == def {
+ def := arg.Type().makeDefaultArg().(*ConstArg)
+ if a.Val == def.Val {
return false
}
v0 := a.Val
- a.Val = def
+ a.Val = def.Val
if ctx.pred(ctx.p, ctx.callIndex0) {
*ctx.p0 = ctx.p
} else {
diff --git a/prog/prog.go b/prog/prog.go
index 53e0fbe33..edfbd762c 100644
--- a/prog/prog.go
+++ b/prog/prog.go
@@ -60,13 +60,13 @@ func (arg *ConstArg) Value() (uint64, uint64) {
return arg.Val, 0
case *LenType:
return arg.Val, 0
+ case *ResourceType:
+ return arg.Val, 0
case *CsumType:
// Checksums are computed dynamically in executor.
return 0, 0
- case *ResourceType:
- return arg.Val, 0
case *ProcType:
- if arg.Val == typ.Default() {
+ if arg.Val == procDefaultValue {
return 0, 0
}
return typ.ValuesStart + arg.Val, typ.ValuesPerProc
@@ -276,119 +276,8 @@ func InnerArg(arg Arg) Arg {
return arg // Not a pointer.
}
-func (target *Target) defaultArg(t Type) Arg {
- switch typ := t.(type) {
- case *IntType, *ConstType, *FlagsType, *LenType, *ProcType, *CsumType:
- return MakeConstArg(t, t.Default())
- case *ResourceType:
- return MakeResultArg(t, nil, typ.Default())
- case *BufferType:
- if t.Dir() == DirOut {
- var sz uint64
- if !typ.Varlen() {
- sz = typ.Size()
- }
- return MakeOutDataArg(t, sz)
- }
- var data []byte
- if !typ.Varlen() {
- data = make([]byte, typ.Size())
- }
- return MakeDataArg(t, data)
- case *ArrayType:
- var elems []Arg
- if typ.Kind == ArrayRangeLen && typ.RangeBegin == typ.RangeEnd {
- for i := uint64(0); i < typ.RangeBegin; i++ {
- elems = append(elems, target.defaultArg(typ.Type))
- }
- }
- return MakeGroupArg(t, elems)
- case *StructType:
- var inner []Arg
- for _, field := range typ.Fields {
- inner = append(inner, target.defaultArg(field))
- }
- return MakeGroupArg(t, inner)
- case *UnionType:
- return MakeUnionArg(t, target.defaultArg(typ.Fields[0]))
- case *VmaType:
- if t.Optional() {
- return MakeNullPointerArg(t)
- }
- return MakeVmaPointerArg(t, 0, target.PageSize)
- case *PtrType:
- if t.Optional() {
- return MakeNullPointerArg(t)
- }
- return MakePointerArg(t, 0, target.defaultArg(typ.Type))
- default:
- panic(fmt.Sprintf("unknown arg type: %#v", t))
- }
-}
-
-func (target *Target) isDefaultArg(arg Arg) bool {
- if IsPad(arg.Type()) {
- return true
- }
- switch a := arg.(type) {
- case *ConstArg:
- switch t := a.Type().(type) {
- case *IntType, *ConstType, *FlagsType, *LenType, *ProcType, *CsumType:
- return a.Val == t.Default()
- default:
- panic(fmt.Sprintf("unknown const type: %#v", t))
- }
- case *GroupArg:
- if !a.fixedInnerSize() && len(a.Inner) != 0 {
- return false
- }
- for _, elem := range a.Inner {
- if !target.isDefaultArg(elem) {
- return false
- }
- }
- return true
- case *UnionArg:
- t := a.Type().(*UnionType)
- return a.Option.Type().FieldName() == t.Fields[0].FieldName() &&
- target.isDefaultArg(a.Option)
- case *DataArg:
- if a.Size() == 0 {
- return true
- }
- if a.Type().Varlen() {
- return false
- }
- if a.Type().Dir() == DirOut {
- return true
- }
- for _, v := range a.Data() {
- if v != 0 {
- return false
- }
- }
- return true
- case *PointerArg:
- switch t := a.Type().(type) {
- case *PtrType:
- if t.Optional() {
- return a.IsNull()
- }
- return a.Address == 0 && target.isDefaultArg(a.Res)
- case *VmaType:
- if t.Optional() {
- return a.IsNull()
- }
- return a.Address == 0 && a.VmaSize == target.PageSize
- default:
- panic(fmt.Sprintf("unknown pointer type: %#v", t))
- }
- case *ResultArg:
- t := a.Type().(*ResourceType)
- return a.Res == nil && a.OpDiv == 0 && a.OpAdd == 0 &&
- len(a.uses) == 0 && a.Val == t.Default()
- }
- return false
+func isDefault(arg Arg) bool {
+ return arg.Type().isDefaultArg(arg)
}
func (p *Prog) insertBefore(c *Call, calls []*Call) {
@@ -456,18 +345,20 @@ func replaceResultArg(arg, arg1 *ResultArg) {
// removeArg removes all references to/from arg0 from a program.
func removeArg(arg0 Arg) {
ForeachSubArg(arg0, func(arg Arg, ctx *ArgCtx) {
- if a, ok := arg.(*ResultArg); ok {
- if a.Res != nil {
- uses := a.Res.uses
- if !uses[a] {
- panic("broken tree")
- }
- delete(uses, a)
- }
- for arg1 := range a.uses {
- arg2 := MakeResultArg(arg1.Type(), nil, arg1.Type().Default())
- replaceResultArg(arg1, arg2)
+ a, ok := arg.(*ResultArg)
+ if !ok {
+ return
+ }
+ if a.Res != nil {
+ uses := a.Res.uses
+ if !uses[a] {
+ panic("broken tree")
}
+ delete(uses, a)
+ }
+ for arg1 := range a.uses {
+ arg2 := arg1.Type().makeDefaultArg().(*ResultArg)
+ replaceResultArg(arg1, arg2)
}
})
}
diff --git a/prog/prog_test.go b/prog/prog_test.go
index 0628b40e5..c3f20bd6d 100644
--- a/prog/prog_test.go
+++ b/prog/prog_test.go
@@ -24,8 +24,8 @@ func TestDefault(t *testing.T) {
target, _, _ := initTest(t)
for _, meta := range target.Syscalls {
ForeachType(meta, func(typ Type) {
- arg := target.defaultArg(typ)
- if !target.isDefaultArg(arg) {
+ arg := typ.makeDefaultArg()
+ if !isDefault(arg) {
t.Errorf("default arg is not default: %s\ntype: %#v\narg: %#v",
typ, typ, arg)
}
diff --git a/prog/rand.go b/prog/rand.go
index 721bbed00..7bded23c6 100644
--- a/prog/rand.go
+++ b/prog/rand.go
@@ -279,7 +279,7 @@ func (r *randGen) createResource(s *state, res *ResourceType) (arg Arg, calls []
metas = append(metas, meta)
}
if len(metas) == 0 {
- return MakeResultArg(res, nil, res.Default()), nil
+ return res.makeDefaultArg(), nil
}
// Now we have a set of candidate calls that can create the necessary resource.
@@ -490,7 +490,7 @@ func (r *randGen) generateArgImpl(s *state, typ Type, ignoreSpecial bool) (arg A
switch typ.(type) {
case *IntType, *FlagsType, *ConstType, *ProcType,
*VmaType, *ResourceType:
- return r.target.defaultArg(typ), nil
+ return typ.makeDefaultArg(), nil
}
}
@@ -499,7 +499,7 @@ func (r *randGen) generateArgImpl(s *state, typ Type, ignoreSpecial bool) (arg A
v := res.Desc.Values[r.Intn(len(res.Desc.Values))]
return MakeResultArg(typ, nil, v), nil
}
- return r.target.defaultArg(typ), nil
+ return typ.makeDefaultArg(), nil
}
// Allow infinite recursion for optional pointers.
diff --git a/prog/types.go b/prog/types.go
index 2e694ef9f..004194707 100644
--- a/prog/types.go
+++ b/prog/types.go
@@ -53,7 +53,6 @@ type Type interface {
FieldName() string
Dir() Dir
Optional() bool
- Default() uint64
Varlen() bool
Size() uint64
Format() BinaryFormat
@@ -61,6 +60,8 @@ type Type interface {
BitfieldLength() uint64
BitfieldMiddle() bool // returns true for all but last bitfield in a group
+ makeDefaultArg() Arg
+ isDefaultArg(arg Arg) bool
generate(r *randGen, s *state) (arg Arg, calls []*Call)
mutate(r *randGen, s *state, arg Arg, ctx ArgCtx) (calls []*Call, retry, preserve bool)
minimize(ctx *minimizeArgsCtx, arg Arg, path string) bool
@@ -94,10 +95,6 @@ func (t *TypeCommon) Optional() bool {
return t.IsOptional
}
-func (t *TypeCommon) Default() uint64 {
- return 0
-}
-
func (t *TypeCommon) Size() uint64 {
if t.IsVarlen {
panic(fmt.Sprintf("static type size is not known: %#v", t))
@@ -146,6 +143,16 @@ func (t *ResourceType) String() string {
return t.Name()
}
+func (t *ResourceType) makeDefaultArg() Arg {
+ return MakeResultArg(t, nil, t.Default())
+}
+
+func (t *ResourceType) isDefaultArg(arg Arg) bool {
+ a := arg.(*ResultArg)
+ return a.Res == nil && a.OpDiv == 0 && a.OpAdd == 0 &&
+ len(a.uses) == 0 && a.Val == t.Default()
+}
+
func (t *ResourceType) Default() uint64 {
return t.Desc.Values[0]
}
@@ -192,8 +199,12 @@ type ConstType struct {
IsPad bool
}
-func (t *ConstType) Default() uint64 {
- return t.Val
+func (t *ConstType) makeDefaultArg() Arg {
+ return MakeConstArg(t, t.Val)
+}
+
+func (t *ConstType) isDefaultArg(arg Arg) bool {
+ return arg.(*ConstArg).Val == t.Val
}
func (t *ConstType) String() string {
@@ -218,29 +229,59 @@ type IntType struct {
RangeEnd uint64
}
+func (t *IntType) makeDefaultArg() Arg {
+ return MakeConstArg(t, 0)
+}
+
+func (t *IntType) isDefaultArg(arg Arg) bool {
+ return arg.(*ConstArg).Val == 0
+}
+
type FlagsType struct {
IntTypeCommon
Vals []uint64
BitMask bool
}
+func (t *FlagsType) makeDefaultArg() Arg {
+ return MakeConstArg(t, 0)
+}
+
+func (t *FlagsType) isDefaultArg(arg Arg) bool {
+ return arg.(*ConstArg).Val == 0
+}
+
type LenType struct {
IntTypeCommon
BitSize uint64 // want size in multiple of bits instead of array size
Buf string
}
+func (t *LenType) makeDefaultArg() Arg {
+ return MakeConstArg(t, 0)
+}
+
+func (t *LenType) isDefaultArg(arg Arg) bool {
+ return arg.(*ConstArg).Val == 0
+}
+
type ProcType struct {
IntTypeCommon
ValuesStart uint64
ValuesPerProc uint64
}
-const MaxPids = 32
+const (
+ MaxPids = 32
+ procDefaultValue = 0xffffffffffffffff // special value denoting 0 for all procs
+)
-func (t *ProcType) Default() uint64 {
- // Special value denoting 0 for all procs.
- return 0xffffffffffffffff
+func (t *ProcType) makeDefaultArg() Arg {
+ return MakeConstArg(t, procDefaultValue)
+}
+
+func (t *ProcType) isDefaultArg(arg Arg) bool {
+ return arg.(*ConstArg).Val == procDefaultValue
}
type CsumKind int
@@ -261,6 +302,14 @@ func (t *CsumType) String() string {
return "csum"
}
+func (t *CsumType) makeDefaultArg() Arg {
+ return MakeConstArg(t, 0)
+}
+
+func (t *CsumType) isDefaultArg(arg Arg) bool {
+ return arg.(*ConstArg).Val == 0
+}
+
type VmaType struct {
TypeCommon
RangeBegin uint64 // in pages
@@ -271,6 +320,14 @@ func (t *VmaType) String() string {
return "vma"
}
+func (t *VmaType) makeDefaultArg() Arg {
+ return MakeNullPointerArg(t)
+}
+
+func (t *VmaType) isDefaultArg(arg Arg) bool {
+ return arg.(*PointerArg).IsNull()
+}
+
type BufferKind int
const (
@@ -306,6 +363,40 @@ func (t *BufferType) String() string {
return "buffer"
}
+func (t *BufferType) makeDefaultArg() Arg {
+ if t.Dir() == DirOut {
+ var sz uint64
+ if !t.Varlen() {
+ sz = t.Size()
+ }
+ return MakeOutDataArg(t, sz)
+ }
+ var data []byte
+ if !t.Varlen() {
+ data = make([]byte, t.Size())
+ }
+ return MakeDataArg(t, data)
+}
+
+func (t *BufferType) isDefaultArg(arg Arg) bool {
+ a := arg.(*DataArg)
+ if a.Size() == 0 {
+ return true
+ }
+ if a.Type().Varlen() {
+ return false
+ }
+ if a.Type().Dir() == DirOut {
+ return true
+ }
+ for _, v := range a.Data() {
+ if v != 0 {
+ return false
+ }
+ }
+ return true
+}
+
type ArrayKind int
const (
@@ -325,6 +416,29 @@ func (t *ArrayType) String() string {
return fmt.Sprintf("array[%v]", t.Type.String())
}
+func (t *ArrayType) makeDefaultArg() Arg {
+ var elems []Arg
+ if t.Kind == ArrayRangeLen && t.RangeBegin == t.RangeEnd {
+ for i := uint64(0); i < t.RangeBegin; i++ {
+ elems = append(elems, t.Type.makeDefaultArg())
+ }
+ }
+ return MakeGroupArg(t, elems)
+}
+
+func (t *ArrayType) isDefaultArg(arg Arg) bool {
+ a := arg.(*GroupArg)
+ if !a.fixedInnerSize() && len(a.Inner) != 0 {
+ return false
+ }
+ for _, elem := range a.Inner {
+ if !t.Type.isDefaultArg(elem) {
+ return false
+ }
+ }
+ return true
+}
+
type PtrType struct {
TypeCommon
Type Type
@@ -334,6 +448,21 @@ func (t *PtrType) String() string {
return fmt.Sprintf("ptr[%v, %v]", t.Dir(), t.Type.String())
}
+func (t *PtrType) makeDefaultArg() Arg {
+ if t.Optional() {
+ return MakeNullPointerArg(t)
+ }
+ return MakePointerArg(t, 0, t.Type.makeDefaultArg())
+}
+
+func (t *PtrType) isDefaultArg(arg Arg) bool {
+ a := arg.(*PointerArg)
+ if t.Optional() {
+ return a.IsNull()
+ }
+ return a.Address == 0 && t.Type.isDefaultArg(a.Res)
+}
+
type StructType struct {
Key StructKey
FldName string
@@ -348,6 +477,24 @@ func (t *StructType) FieldName() string {
return t.FldName
}
+func (t *StructType) makeDefaultArg() Arg {
+ inner := make([]Arg, len(t.Fields))
+ for i, field := range t.Fields {
+ inner[i] = field.makeDefaultArg()
+ }
+ return MakeGroupArg(t, inner)
+}
+
+func (t *StructType) isDefaultArg(arg Arg) bool {
+ a := arg.(*GroupArg)
+ for i, elem := range a.Inner {
+ if !t.Fields[i].isDefaultArg(elem) {
+ return false
+ }
+ }
+ return true
+}
+
type UnionType struct {
Key StructKey
FldName string
@@ -362,6 +509,16 @@ func (t *UnionType) FieldName() string {
return t.FldName
}
+func (t *UnionType) makeDefaultArg() Arg {
+ return MakeUnionArg(t, t.Fields[0].makeDefaultArg())
+}
+
+func (t *UnionType) isDefaultArg(arg Arg) bool {
+ a := arg.(*UnionArg)
+ return a.Option.Type().FieldName() == t.Fields[0].FieldName() &&
+ t.Fields[0].isDefaultArg(a.Option)
+}
+
type StructDesc struct {
TypeCommon
Fields []Type
diff --git a/prog/validation.go b/prog/validation.go
index 5f53e48aa..af27d4187 100644
--- a/prog/validation.go
+++ b/prog/validation.go
@@ -90,20 +90,18 @@ func (ctx *validCtx) validateArg(arg Arg) error {
func (arg *ConstArg) validate(ctx *validCtx) error {
switch typ := arg.Type().(type) {
case *IntType:
- if typ.Dir() == DirOut && (arg.Val != 0 && arg.Val != typ.Default()) {
+ if typ.Dir() == DirOut && !isDefault(arg) {
return fmt.Errorf("out int arg '%v' has bad const value %v", typ.Name(), arg.Val)
}
case *ProcType:
- if arg.Val >= typ.ValuesPerProc && arg.Val != typ.Default() {
+ if arg.Val >= typ.ValuesPerProc && !isDefault(arg) {
return fmt.Errorf("per proc arg '%v' has bad value %v", typ.Name(), arg.Val)
}
case *CsumType:
if arg.Val != 0 {
return fmt.Errorf("csum arg '%v' has nonzero value %v", typ.Name(), arg.Val)
}
- case *ConstType:
- case *FlagsType:
- case *LenType:
+ case *ConstType, *FlagsType, *LenType:
default:
return fmt.Errorf("const arg %v has bad type %v", arg, typ.Name())
}
@@ -111,7 +109,7 @@ func (arg *ConstArg) validate(ctx *validCtx) error {
// We generate output len arguments, which makes sense since it can be
// a length of a variable-length array which is not known otherwise.
if _, isLen := typ.(*LenType); !isLen {
- if arg.Val != 0 && arg.Val != typ.Default() {
+ if !typ.isDefaultArg(arg) {
return fmt.Errorf("output arg '%v'/'%v' has non default value '%+v'",
typ.FieldName(), typ.Name(), arg)
}
@@ -134,7 +132,7 @@ func (arg *ResultArg) validate(ctx *validCtx) error {
}
ctx.uses[u] = arg
}
- if typ.Dir() == DirOut && (arg.Val != 0 && arg.Val != typ.Default()) {
+ if typ.Dir() == DirOut && arg.Val != 0 && arg.Val != typ.Default() {
return fmt.Errorf("out resource arg '%v' has bad const value %v", typ.Name(), arg.Val)
}
if arg.Res != nil {
@@ -229,9 +227,6 @@ func (arg *PointerArg) validate(ctx *validCtx) error {
if arg.Res != nil {
return fmt.Errorf("vma arg '%v' has data", typ.Name())
}
- if arg.VmaSize == 0 && typ.Dir() != DirOut && !typ.Optional() {
- return fmt.Errorf("vma arg '%v' has size 0", typ.Name())
- }
case *PtrType:
if arg.Res == nil && !arg.Type().Optional() {
return fmt.Errorf("non optional pointer arg '%v' is nil", typ.Name())