mirror of
https://github.com/golang/go
synced 2024-11-20 10:44:41 -07:00
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>
This commit is contained in:
parent
53fc330e2d
commit
7a26d9fced
@ -28,6 +28,8 @@ type parser struct {
|
|||||||
nerrors int // error count
|
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) {
|
func (p *parser) init(src io.Reader, errh ErrorHandler, pragh PragmaHandler) {
|
||||||
p.scanner.init(src, func(pos, line int, msg string) {
|
p.scanner.init(src, func(pos, line int, msg string) {
|
||||||
p.nerrors++
|
p.nerrors++
|
||||||
@ -35,7 +37,7 @@ func (p *parser) init(src io.Reader, errh ErrorHandler, pragh PragmaHandler) {
|
|||||||
errh(pos, line, msg)
|
errh(pos, line, msg)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
panic(fmt.Sprintf("%d: %s\n", line, msg))
|
panic(parserError(fmt.Sprintf("%d: %s\n", line, msg)))
|
||||||
}, pragh)
|
}, pragh)
|
||||||
|
|
||||||
p.fnest = 0
|
p.fnest = 0
|
||||||
|
@ -155,3 +155,10 @@ func verifyPrint(filename string, ast1 *File) {
|
|||||||
panic("not equal")
|
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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
package syntax
|
package syntax
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
@ -52,18 +53,31 @@ func ReadBytes(src []byte, errh ErrorHandler, pragh PragmaHandler, mode Mode) (*
|
|||||||
return Read(&bytesReader{src}, errh, pragh, 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
|
var p parser
|
||||||
p.init(src, errh, pragh)
|
p.init(src, errh, pragh)
|
||||||
|
|
||||||
p.next()
|
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 {
|
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 {
|
func Write(w io.Writer, n *File) error {
|
||||||
|
Loading…
Reference in New Issue
Block a user