From a4a4d43028ba20ecec50ef761012d17800553cde Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 2 Nov 2016 20:18:47 -0400 Subject: [PATCH] cmd/cover: change covered block for switch/select case to exclude expression Consider a switch like switch x { case foo: f() g() } Before, the coverage annotation for the block calling f and g included in its position span the text for 'case foo:'. This looks nice in the coverage report, but it breaks the invariant that coverage blocks are disjoint if you have a more complex expression like: switch x { case func() int { return foo }(): f() g() } Then the coverage analysis wants to annotate the func literal body, which overlaps with the case body, because the case body is considered to begin at the case token. Change the annotation for a case body to start just after the colon of the case clause, avoiding any potential conflict with complex case expressions. Could have started at the colon instead, but it seemed less weird to start just after it. Fixes #16540. Change-Id: I1fec4bc2a53c7092e649dc0d4be1680a697cb79b Reviewed-on: https://go-review.googlesource.com/32612 Run-TryBot: Russ Cox Reviewed-by: Andrew Gerrand --- src/cmd/cover/cover.go | 4 ++-- src/cmd/cover/testdata/test.go | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/cmd/cover/cover.go b/src/cmd/cover/cover.go index 222737571fb..b7d9125d60a 100644 --- a/src/cmd/cover/cover.go +++ b/src/cmd/cover/cover.go @@ -168,13 +168,13 @@ func (f *File) Visit(node ast.Node) ast.Visitor { case *ast.CaseClause: // switch for _, n := range n.List { clause := n.(*ast.CaseClause) - clause.Body = f.addCounters(clause.Pos(), clause.End(), clause.Body, false) + clause.Body = f.addCounters(clause.Colon+1, clause.End(), clause.Body, false) } return f case *ast.CommClause: // select for _, n := range n.List { clause := n.(*ast.CommClause) - clause.Body = f.addCounters(clause.Pos(), clause.End(), clause.Body, false) + clause.Body = f.addCounters(clause.Colon+1, clause.End(), clause.Body, false) } return f } diff --git a/src/cmd/cover/testdata/test.go b/src/cmd/cover/testdata/test.go index 71cb1153313..61b40eaa740 100644 --- a/src/cmd/cover/testdata/test.go +++ b/src/cmd/cover/testdata/test.go @@ -246,6 +246,18 @@ func testFunctionLiteral() { check(LINE, 2) }) { } + + x := 2 + switch x { + case func() int { check(LINE, 1); return 1 }(): + check(LINE, 0) + panic("2=1") + case func() int { check(LINE, 1); return 2 }(): + check(LINE, 1) + case func() int { check(LINE, 0); return 3 }(): + check(LINE, 0) + panic("2=3") + } } func testGoto() {