]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/cover: fix counting of blocks split by goto statements
authorAndrew Gerrand <adg@golang.org>
Fri, 31 May 2019 06:58:44 +0000 (16:58 +1000)
committerAndrew Gerrand <adg@golang.org>
Mon, 3 Jun 2019 01:37:58 +0000 (01:37 +0000)
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 <r@golang.org>
src/cmd/cover/cover.go
src/cmd/cover/testdata/test.go

index 1748606c5e7119f7eb24df4f659cbf85f6e5c0bd..e04c8834bd8cf3f977ef2d60982f47a853f48c9e 100644 (file)
@@ -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 {
index 0b03ef91ab559ab57705fa3a32d39d4339fb9928..b794962205d3da7f8cdf9c37c43fecdc0473e81e 100644 (file)
@@ -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)