diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2024-03-12 11:06:01 +0100 |
|---|---|---|
| committer | Aleksandr Nogikh <nogikh@google.com> | 2024-03-13 10:31:21 +0000 |
| commit | 3374743756461ab01a88a056ff039393a7b73a49 (patch) | |
| tree | b535640a2449530d4b84d9d4176e5825bc01b8c5 /prog/prog.go | |
| parent | 43c7f3875016259bbb877ac58b831af47c92f06d (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().
Diffstat (limited to 'prog/prog.go')
| -rw-r--r-- | prog/prog.go | 20 |
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)) } |
