cover: handle multiple samples from the same location

This change is ported from src/cmd/cover/profile.go[1].

Now that go test supported -coverprofile with multiple packages (#6909),
x/tools/cover/profile should also handle multiple samples from the same
location.

[1]: https://github.com/golang/go/commit/f39050c8ebf894ccedc0b99de96f7412be97af89

Fixes golang/go#23076

Change-Id: I1b1d664bf56f7e22c6cb2726df44fb577408c6f7
Reviewed-on: https://go-review.googlesource.com/83078
Run-TryBot: Rob Pike <r@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
diff --git a/cover/profile.go b/cover/profile.go
index 958881a..b6c8120 100644
--- a/cover/profile.go
+++ b/cover/profile.go
@@ -91,6 +91,29 @@
 	}
 	for _, p := range files {
 		sort.Sort(blocksByStart(p.Blocks))
+		// Merge samples from the same location.
+		j := 1
+		for i := 1; i < len(p.Blocks); i++ {
+			b := p.Blocks[i]
+			last := p.Blocks[j-1]
+			if b.StartLine == last.StartLine &&
+				b.StartCol == last.StartCol &&
+				b.EndLine == last.EndLine &&
+				b.EndCol == last.EndCol {
+				if b.NumStmt != last.NumStmt {
+					return nil, fmt.Errorf("inconsistent NumStmt: changed from %d to %d", last.NumStmt, b.NumStmt)
+				}
+				if mode == "set" {
+					p.Blocks[j-1].Count |= b.Count
+				} else {
+					p.Blocks[j-1].Count += b.Count
+				}
+				continue
+			}
+			p.Blocks[j] = b
+			j++
+		}
+		p.Blocks = p.Blocks[:j]
 	}
 	// Generate a sorted slice.
 	profiles := make([]*Profile, 0, len(files))