]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/cover: don't try to attach directives to synthetic decls
authorJay Conrod <jayconrod@google.com>
Tue, 17 Oct 2017 19:33:45 +0000 (15:33 -0400)
committerRobert Griesemer <gri@golang.org>
Tue, 17 Oct 2017 22:14:28 +0000 (22:14 +0000)
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 <jayconrod@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/cmd/cover/cover.go
src/cmd/cover/cover_test.go

index 8bcdec17c8d9bf56093ce98214cbc3f5ca15ecc0..5bea3b11aa5978374be3b4cdb3a5b1dfd90854ed 100644 (file)
@@ -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) {
index 8c9acc93f6557a933318bd8569fec445a2e21423..4d8826b96db89af27ac743838678ca7673d3f522 100644 (file)
@@ -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 {