[release-branch.go1.20] internal/coverage/decodemeta: fix coding error in func literal handling

Fix a coding error in coverage meta-data decoding in the method
decodemeta.CoverageMetaDataDecoder.ReadFunc. The code was not
unconditionally assigning the "function literal" field of the
coverage.FuncDesc object passed in, resulting in bad values depending
on what the state of the field happened to be in the object.

Fixes #57942.

Change-Id: I6dfd7d7f7af6004f05c622f9a7116e9f6018cf4f
Reviewed-on: https://go-review.googlesource.com/c/go/+/462955
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
(cherry picked from commit 620399ef0d)
Reviewed-on: https://go-review.googlesource.com/c/go/+/463418
Reviewed-by: Than McIntosh <thanm@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Than McIntosh 2023-01-20 14:03:43 -05:00 committed by Matthew Dempsky
parent be7e4fee4b
commit 52bd3b186b
3 changed files with 57 additions and 3 deletions

View File

@ -288,6 +288,7 @@ func (d *dstate) VisitFunc(pkgIdx uint32, fnIdx uint32, fd *coverage.FuncDesc) {
}
fmt.Printf("\nFunc: %s\n", fd.Funcname)
fmt.Printf("Srcfile: %s\n", fd.Srcfile)
fmt.Printf("Literal: %v\n", fd.Lit)
}
for i := 0; i < len(fd.Units); i++ {
u := fd.Units[i]

View File

@ -123,8 +123,6 @@ func (d *CoverageMetaDataDecoder) ReadFunc(fidx uint32, f *coverage.FuncDesc) er
})
}
lit := d.r.ReadULEB128()
if lit != 0 {
f.Lit = true
}
f.Lit = lit != 0
return nil
}

View File

@ -274,3 +274,58 @@ func TestMetaDataWriterReader(t *testing.T) {
inf.Close()
}
}
func TestMetaDataDecodeLitFlagIssue57942(t *testing.T) {
// Encode a package with a few functions. The funcs alternate
// between regular functions and function literals.
pp := "foo/bar/pkg"
pn := "pkg"
mp := "barmod"
b, err := encodemeta.NewCoverageMetaDataBuilder(pp, pn, mp)
if err != nil {
t.Fatalf("making builder: %v", err)
}
const NF = 6
const NCU = 1
ln := uint32(10)
wantfds := []coverage.FuncDesc{}
for fi := uint32(0); fi < NF; fi++ {
fis := fmt.Sprintf("%d", fi)
fd := coverage.FuncDesc{
Funcname: "func" + fis,
Srcfile: "foo" + fis + ".go",
Units: []coverage.CoverableUnit{
coverage.CoverableUnit{StLine: ln + 1, StCol: 2, EnLine: ln + 3, EnCol: 4, NxStmts: fi + 2},
},
Lit: (fi % 2) == 0,
}
wantfds = append(wantfds, fd)
b.AddFunc(fd)
}
// Emit into a writer.
drws := &slicewriter.WriteSeeker{}
b.Emit(drws)
// Decode the result.
drws.Seek(0, io.SeekStart)
dec, err := decodemeta.NewCoverageMetaDataDecoder(drws.BytesWritten(), false)
if err != nil {
t.Fatalf("making decoder: %v", err)
}
nf := dec.NumFuncs()
if nf != NF {
t.Fatalf("decoder number of functions: got %d want %d", nf, NF)
}
var fn coverage.FuncDesc
for i := uint32(0); i < uint32(NF); i++ {
if err := dec.ReadFunc(i, &fn); err != nil {
t.Fatalf("err reading function %d: %v", i, err)
}
res := cmpFuncDesc(wantfds[i], fn)
if res != "" {
t.Errorf("ReadFunc(%d): %s", i, res)
}
}
}