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 <r@golang.org>
diff --git a/src/cmd/cover/cover.go b/src/cmd/cover/cover.go
index 1748606..e04c883 100644
--- a/src/cmd/cover/cover.go
+++ b/src/cmd/cover/cover.go
@@ -386,6 +386,9 @@
 		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 0b03ef9..b794962 100644
--- a/src/cmd/cover/testdata/test.go
+++ b/src/cmd/cover/testdata/test.go
@@ -132,6 +132,10 @@
 
 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)