aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/syntax
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2016-10-31 16:58:15 -0700
committerRobert Griesemer <gri@golang.org>2016-11-01 05:18:47 +0000
commit7a26d9fcedd94a1ba0d95833b0cdbbdcc776fe19 (patch)
tree313c90278a6268c3f1b20eb4e6fe87ef8e086caf /src/cmd/compile/internal/syntax
parent53fc330e2d154443acf3d01e0d68bae22b2b7804 (diff)
downloadgo-7a26d9fcedd94a1ba0d95833b0cdbbdcc776fe19.tar.xz
cmd/compile/internal/syntax: don't panic if no error handler is provided
If no error handler is provided, terminate parsing with first error and report that error. Fixes #17697. Change-Id: I9070faf7239bd53725de141507912b92ded3474b Reviewed-on: https://go-review.googlesource.com/32456 Run-TryBot: Robert Griesemer <gri@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'src/cmd/compile/internal/syntax')
-rw-r--r--src/cmd/compile/internal/syntax/parser.go4
-rw-r--r--src/cmd/compile/internal/syntax/parser_test.go7
-rw-r--r--src/cmd/compile/internal/syntax/syntax.go24
3 files changed, 29 insertions, 6 deletions
diff --git a/src/cmd/compile/internal/syntax/parser.go b/src/cmd/compile/internal/syntax/parser.go
index fcf4f5b692..1ed20651b1 100644
--- a/src/cmd/compile/internal/syntax/parser.go
+++ b/src/cmd/compile/internal/syntax/parser.go
@@ -28,6 +28,8 @@ type parser struct {
nerrors int // error count
}
+type parserError string // for error recovery if no error handler was installed
+
func (p *parser) init(src io.Reader, errh ErrorHandler, pragh PragmaHandler) {
p.scanner.init(src, func(pos, line int, msg string) {
p.nerrors++
@@ -35,7 +37,7 @@ func (p *parser) init(src io.Reader, errh ErrorHandler, pragh PragmaHandler) {
errh(pos, line, msg)
return
}
- panic(fmt.Sprintf("%d: %s\n", line, msg))
+ panic(parserError(fmt.Sprintf("%d: %s\n", line, msg)))
}, pragh)
p.fnest = 0
diff --git a/src/cmd/compile/internal/syntax/parser_test.go b/src/cmd/compile/internal/syntax/parser_test.go
index 8e6b77d0c6..780f10835c 100644
--- a/src/cmd/compile/internal/syntax/parser_test.go
+++ b/src/cmd/compile/internal/syntax/parser_test.go
@@ -155,3 +155,10 @@ func verifyPrint(filename string, ast1 *File) {
panic("not equal")
}
}
+
+func TestIssue17697(t *testing.T) {
+ _, err := ReadBytes(nil, nil, nil, 0) // return with parser error, don't panic
+ if err == nil {
+ t.Errorf("no error reported")
+ }
+}
diff --git a/src/cmd/compile/internal/syntax/syntax.go b/src/cmd/compile/internal/syntax/syntax.go
index 49831d0fbd..71fc097c3b 100644
--- a/src/cmd/compile/internal/syntax/syntax.go
+++ b/src/cmd/compile/internal/syntax/syntax.go
@@ -5,6 +5,7 @@
package syntax
import (
+ "errors"
"fmt"
"io"
"os"
@@ -52,18 +53,31 @@ func ReadBytes(src []byte, errh ErrorHandler, pragh PragmaHandler, mode Mode) (*
return Read(&bytesReader{src}, errh, pragh, mode)
}
-func Read(src io.Reader, errh ErrorHandler, pragh PragmaHandler, mode Mode) (*File, error) {
+func Read(src io.Reader, errh ErrorHandler, pragh PragmaHandler, mode Mode) (ast *File, err error) {
+ defer func() {
+ if p := recover(); p != nil {
+ if msg, ok := p.(parserError); ok {
+ err = errors.New(string(msg))
+ return
+ }
+ panic(p)
+ }
+ }()
+
var p parser
p.init(src, errh, pragh)
-
p.next()
- ast := p.file()
+ ast = p.file()
+ // TODO(gri) This isn't quite right: Even if there's an error handler installed
+ // we should report an error if parsing found syntax errors. This also
+ // requires updating the noder's ReadFile call.
if errh == nil && p.nerrors > 0 {
- return nil, fmt.Errorf("%d syntax errors", p.nerrors)
+ ast = nil
+ err = fmt.Errorf("%d syntax errors", p.nerrors)
}
- return ast, nil
+ return
}
func Write(w io.Writer, n *File) error {