From: Andrew Gerrand Date: Fri, 31 May 2019 06:58:44 +0000 (+1000) Subject: cmd/cover: fix counting of blocks split by goto statements X-Git-Tag: go1.13beta1~158 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=98100c56da0da1503e7612921eff821409aa6cce;p=gostls13.git cmd/cover: fix counting of blocks split by goto statements When adding coverage counters to a block, the block's statement list is mutated. CL 77150 removed the part where the mutated list is assigned back to its parent node; this was confusing ast.Walk, which would then lose its place and stop walking the current block, dropping counters in the process. This change has addCounters make a copy of the list before mutating it, so that the original list doesn't change under Walk's feet. Fix #32200 Change-Id: Ia3b67d8cee860ceb7caf8748cb7a80ff9c6276e0 Reviewed-on: https://go-review.googlesource.com/c/go/+/179581 Reviewed-by: Rob Pike --- diff --git a/src/cmd/cover/cover.go b/src/cmd/cover/cover.go index 1748606c5e..e04c8834bd 100644 --- a/src/cmd/cover/cover.go +++ b/src/cmd/cover/cover.go @@ -386,6 +386,9 @@ func (f *File) addCounters(pos, insertPos, blockEnd token.Pos, list []ast.Stmt, f.edit.Insert(f.offset(insertPos), f.newCounter(insertPos, blockEnd, 0)+";") return } + // Make a copy of the list, as we may mutate it and should leave the + // existing list intact. + list = append([]ast.Stmt(nil), list...) // We have a block (statement list), but it may have several basic blocks due to the // appearance of statements that affect the flow of control. for { diff --git a/src/cmd/cover/testdata/test.go b/src/cmd/cover/testdata/test.go index 0b03ef91ab..b794962205 100644 --- a/src/cmd/cover/testdata/test.go +++ b/src/cmd/cover/testdata/test.go @@ -132,6 +132,10 @@ func testBlockRun() { func testSwitch() { for i := 0; i < 5; func() { i++; check(LINE, 5) }() { + goto label2 + label1: + goto label1 + label2: switch i { case 0: check(LINE, 1)