]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix contrived line number errors
authorMatthew Dempsky <mdempsky@google.com>
Fri, 26 Feb 2016 06:10:48 +0000 (22:10 -0800)
committerMatthew Dempsky <mdempsky@google.com>
Fri, 26 Feb 2016 21:25:43 +0000 (21:25 +0000)
If a general comment contains multiple newline characters, we can't
simply unread one and then re-lex it via the general whitespace lexing
phase, because then we'll reset lineno to the line before the "*/"
marker, rather than keeping it where we found the "/*" marker.

Also, for processing imports, call importfile before advancing the
lexer with p.next(), so that lineno reflects the line where we found
the import path, and not the token afterwards.

Fixes #14520.

Change-Id: I785a2d83d632280113d4b757de0d57c88ba2caf4
Reviewed-on: https://go-review.googlesource.com/19934
Reviewed-by: Robert Griesemer <gri@golang.org>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/compile/internal/gc/lex.go
src/cmd/compile/internal/gc/parser.go
test/fixedbugs/issue14520.go [new file with mode: 0644]

index 01423000630140d2c00655d4a8cac907f8bc8daf..502859c8fc9800489f6c8ebdaacc47332ab1f047 100644 (file)
@@ -1000,31 +1000,31 @@ l0:
        case '/':
                c1 = l.getr()
                if c1 == '*' {
-                       nl := false
+                       c = l.getr()
                        for {
-                               c = l.getr()
-                               if c == '\n' {
-                                       nl = true
-                               }
-                               for c == '*' {
+                               if c == '*' {
                                        c = l.getr()
                                        if c == '/' {
-                                               if nl {
-                                                       l.ungetr('\n')
-                                               }
-                                               goto l0
-                                       }
-
-                                       if c == '\n' {
-                                               nl = true
+                                               break
                                        }
+                                       continue
                                }
-
                                if c == EOF {
                                        Yyerror("eof in comment")
                                        errorexit()
                                }
+                               c = l.getr()
                        }
+
+                       // A comment containing newlines acts like a newline.
+                       if lexlineno > lineno && nlsemi {
+                               if Debug['x'] != 0 {
+                                       fmt.Printf("lex: implicit semi\n")
+                               }
+                               l.tok = ';'
+                               return
+                       }
+                       goto l0
                }
 
                if c1 == '/' {
index 88d45118da132b9937f8bc56573e81534cfca476..5a67a3fa3a3c8ba65bb1f83ce7985bac692bb062 100644 (file)
@@ -333,20 +333,22 @@ func (p *parser) importdcl() {
        }
 
        line := int32(parserline())
-       path := p.val
-       p.next()
 
-       importfile(&path, p.indent)
-       if importpkg == nil {
+       // We need to clear importpkg before calling p.next(),
+       // otherwise it will affect lexlineno.
+       // TODO(mdempsky): Fix this clumsy API.
+       importfile(&p.val, p.indent)
+       ipkg := importpkg
+       importpkg = nil
+
+       p.next()
+       if ipkg == nil {
                if nerrors == 0 {
                        Fatalf("phase error in import")
                }
                return
        }
 
-       ipkg := importpkg
-       importpkg = nil
-
        ipkg.Direct = true
 
        if my == nil {
diff --git a/test/fixedbugs/issue14520.go b/test/fixedbugs/issue14520.go
new file mode 100644 (file)
index 0000000..43c48b5
--- /dev/null
@@ -0,0 +1,14 @@
+// errorcheck
+
+// Copyright 2016 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package f
+
+import /* // ERROR "import path" */ `
+bogus`
+
+func f(x int /* // ERROR "unexpected semicolon"
+
+*/)