aboutsummaryrefslogtreecommitdiffstats
path: root/prog
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2023-09-20 14:35:47 +0200
committerAleksandr Nogikh <nogikh@google.com>2023-09-28 09:53:32 +0000
commit746f61e725ad2460e3f101b5e8899105ddea08a1 (patch)
tree16504ca1ef7d98f67d221e59c449266402d84c01 /prog
parentf73e09b3a31addec5481c03b113a17cc839ded1f (diff)
prog: preserve inout direction during squashing
Prohibit arg direction from being DirIn if other calls use the resource as input. Fix one case where we used to violate it - during argument squashing. Reported-by: John Miller <jm3228520@gmail.com>
Diffstat (limited to 'prog')
-rw-r--r--prog/any.go1
-rw-r--r--prog/prog.go2
-rw-r--r--prog/validation.go7
3 files changed, 7 insertions, 3 deletions
diff --git a/prog/any.go b/prog/any.go
index 858220440..b99e64932 100644
--- a/prog/any.go
+++ b/prog/any.go
@@ -250,7 +250,6 @@ func (target *Target) squashResult(arg *ResultArg, elems *[]Arg) {
panic("bad")
}
arg.ref = typ.ref()
- arg.dir = DirIn
*elems = append(*elems, MakeUnionArg(target.any.union, DirIn, arg, index))
}
diff --git a/prog/prog.go b/prog/prog.go
index bb7caa7c5..1453e6aea 100644
--- a/prog/prog.go
+++ b/prog/prog.go
@@ -45,7 +45,7 @@ type Arg interface {
Dir() Dir
Size() uint64
- validate(ctx *validCtx) error
+ validate(ctx *validCtx, dir Dir) error
serialize(ctx *serializer)
}
diff --git a/prog/validation.go b/prog/validation.go
index 2672507db..09c3cd64c 100644
--- a/prog/validation.go
+++ b/prog/validation.go
@@ -94,7 +94,12 @@ func (ctx *validCtx) validateArg(arg Arg, typ Type, dir Dir) error {
if _, ok := typ.(*PtrType); ok {
dir = DirIn // pointers are always in
}
- if arg.Dir() != dir {
+ // We used to demand that Arg has exactly the same dir as Type, however,
+ // it leads to problems when dealing with ANYRES* types.
+ // If the resource was DirIn before squashing, we should not demand that
+ // it be DirInOut - it would only lead to mutations that make little sense.
+ // Let's only deny truly conflicting directions, e.g. DirIn vs DirOut.
+ if arg.Dir() != dir && dir != DirInOut {
return fmt.Errorf("arg %#v type %v has wrong dir %v, expect %v", arg, arg.Type(), arg.Dir(), dir)
}
if !ctx.target.isAnyPtr(arg.Type()) && arg.Type() != typ {