From: Jay Conrod Date: Tue, 17 Oct 2017 19:33:45 +0000 (-0400) Subject: cmd/cover: don't try to attach directives to synthetic decls X-Git-Tag: go1.10beta1~679 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=94e3a304524b6090686ace233a8bba97aa4f306a;p=gostls13.git cmd/cover: don't try to attach directives to synthetic decls Fixed an error that occurred in atomic mode. cover adds a global variable declaration that forces sync/atomic to be used. fixDirectives was confused by this declaration since it has an invalid position. These declarations are now skipped. Fixes #22309 Change-Id: I84f5fec13ef847fca35ad49f7704fb93b60503e0 Reviewed-on: https://go-review.googlesource.com/71351 Run-TryBot: Jay Conrod TryBot-Result: Gobot Gobot Reviewed-by: Robert Griesemer --- diff --git a/src/cmd/cover/cover.go b/src/cmd/cover/cover.go index 8bcdec17c8..5bea3b11aa 100644 --- a/src/cmd/cover/cover.go +++ b/src/cmd/cover/cover.go @@ -258,29 +258,48 @@ func (f *File) Visit(node ast.Node) ast.Visitor { func (f *File) fixDirectives() []*ast.Comment { // Scan comments in the file and collect directives. Detach all comments. var directives []*ast.Comment + prev := token.NoPos // smaller than any valid token.Pos for _, cg := range f.astFile.Comments { for _, c := range cg.List { // Skip directives that will be included by initialComments, i.e., those // before the package declaration but not in the file doc comment group. if f.isDirective(c) && (c.Pos() >= f.astFile.Package || cg == f.astFile.Doc) { + // Assume (but verify) that comments are sorted by position. + pos := c.Pos() + if !pos.IsValid() { + log.Fatalf("compiler directive has no position: %q", c.Text) + } else if pos < prev { + log.Fatalf("compiler directives are out of order. %s was before %s.", + f.fset.Position(prev), f.fset.Position(pos)) + } + prev = pos + directives = append(directives, c) } } cg.List = nil } f.astFile.Comments = nil // force printer to use node comments + if len(directives) == 0 { + // Common case: no directives to attach. + return nil + } // Iterate over top-level declarations and attach preceding directives. di := 0 - var prevPos token.Pos + prev = token.NoPos for _, decl := range f.astFile.Decls { - // Assume (but verify) that comments are sorted by position. + // Assume (but verify) that declarations are sorted by position. pos := decl.Pos() - if pos < prevPos { - log.Fatalf("comments are out of order. %s was before %s.", - f.fset.Position(prevPos), f.fset.Position(pos)) + if !pos.IsValid() { + // Synthetic decl. Don't add directives. + continue + } + if pos < prev { + log.Fatalf("declarations are out of order. %s was before %s.", + f.fset.Position(prev), f.fset.Position(pos)) } - prevPos = pos + prev = pos var doc **ast.CommentGroup switch d := decl.(type) { diff --git a/src/cmd/cover/cover_test.go b/src/cmd/cover/cover_test.go index 8c9acc93f6..4d8826b96d 100644 --- a/src/cmd/cover/cover_test.go +++ b/src/cmd/cover/cover_test.go @@ -121,8 +121,8 @@ func TestDirectives(t *testing.T) { } sourceDirectives := findDirectives(source) - // go tool cover -mode=set ./testdata/directives.go - cmd := exec.Command(testenv.GoToolPath(t), "tool", "cover", "-mode=set", testDirectives) + // go tool cover -mode=atomic ./testdata/directives.go + cmd := exec.Command(testenv.GoToolPath(t), "tool", "cover", "-mode=atomic", testDirectives) cmd.Stderr = os.Stderr output, err := cmd.Output() if err != nil {