aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2024-03-12 11:06:01 +0100
committerAleksandr Nogikh <nogikh@google.com>2024-03-13 10:31:21 +0000
commit3374743756461ab01a88a056ff039393a7b73a49 (patch)
treeb535640a2449530d4b84d9d4176e5825bc01b8c5
parent43c7f3875016259bbb877ac58b831af47c92f06d (diff)
prog: tolerate differing array sizes in replaceArg
Structs may not change, but for arrays it's pretty normal. Let's remove this source of subtle panics by supporting arrays of differing sizes in replaceArg().
-rw-r--r--prog/prog.go20
1 files changed, 18 insertions, 2 deletions
diff --git a/prog/prog.go b/prog/prog.go
index da6f158bc..6b4853c7a 100644
--- a/prog/prog.go
+++ b/prog/prog.go
@@ -372,15 +372,31 @@ func replaceArg(arg, arg1 Arg) {
case *DataArg:
*a = *arg1.(*DataArg)
case *GroupArg:
+ _, isStruct := arg.Type().(*StructType)
a1 := arg1.(*GroupArg)
- if len(a.Inner) != len(a1.Inner) {
+ if isStruct && len(a.Inner) != len(a1.Inner) {
panic(fmt.Sprintf("replaceArg: group fields don't match: %v/%v",
len(a.Inner), len(a1.Inner)))
}
a.ArgCommon = a1.ArgCommon
- for i := range a.Inner {
+ // Replace min(|a|, |a1|) arguments.
+ for i := 0; i < len(a.Inner) && i < len(a1.Inner); i++ {
replaceArg(a.Inner[i], a1.Inner[i])
}
+ // Remove extra arguments of a.
+ for len(a.Inner) > len(a1.Inner) {
+ i := len(a.Inner) - 1
+ removeArg(a.Inner[i])
+ a.Inner[i] = nil
+ a.Inner = a.Inner[:i]
+ }
+ // Add extra arguments to a.
+ for i := len(a.Inner); i < len(a1.Inner); i++ {
+ a.Inner = append(a.Inner, a1.Inner[i])
+ }
+ if debug && len(a.Inner) != len(a1.Inner) {
+ panic("replaceArg implementation bug")
+ }
default:
panic(fmt.Sprintf("replaceArg: bad arg kind %#v", arg))
}