mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile/internal/syntax: consider function nesting for error recovery
This re-enables functionality that inadvertently was disabled in the (long) past. Also, don't perform branch checks if we had errors in a function to avoid spurious errors or (worst-case) crashes. Slightly modified test/fixedbugs/issue14006.go to make sure the test still reports invalid label errors (the surrounding function must be syntactically correct). Change-Id: Id5642930877d7cf3400649094ec75c753b5084b7 Reviewed-on: https://go-review.googlesource.com/69770 Run-TryBot: Robert Griesemer <gri@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
39edffb6b1
commit
68e390304e
2 changed files with 15 additions and 9 deletions
|
|
@ -23,6 +23,7 @@ type parser struct {
|
|||
scanner
|
||||
|
||||
first error // first error encountered
|
||||
errcnt int // number of errors encountered
|
||||
pragma Pragma // pragma flags
|
||||
|
||||
fnest int // function nesting level (for error handling)
|
||||
|
|
@ -57,6 +58,7 @@ func (p *parser) init(base *src.PosBase, r io.Reader, errh ErrorHandler, pragh P
|
|||
)
|
||||
|
||||
p.first = nil
|
||||
p.errcnt = 0
|
||||
p.pragma = 0
|
||||
|
||||
p.fnest = 0
|
||||
|
|
@ -114,6 +116,7 @@ func (p *parser) error_at(pos src.Pos, msg string) {
|
|||
if p.first == nil {
|
||||
p.first = err
|
||||
}
|
||||
p.errcnt++
|
||||
if p.errh == nil {
|
||||
panic(p.first)
|
||||
}
|
||||
|
|
@ -179,7 +182,6 @@ const stopset uint64 = 1<<_Break |
|
|||
1<<_Defer |
|
||||
1<<_Fallthrough |
|
||||
1<<_For |
|
||||
1<<_Func |
|
||||
1<<_Go |
|
||||
1<<_Goto |
|
||||
1<<_If |
|
||||
|
|
@ -495,17 +497,18 @@ func (p *parser) funcDeclOrNil() *FuncDecl {
|
|||
}
|
||||
|
||||
func (p *parser) funcBody() *BlockStmt {
|
||||
// TODO(gri) If we are in a function we should update p.fnest
|
||||
// accordingly. Currently p.fnest is always zero and thus not
|
||||
// used in error recovery.
|
||||
// Not enabled because it performs worse for some code without
|
||||
// more fine tuning (see example in #22164).
|
||||
// p.fnest++
|
||||
p.fnest++
|
||||
errcnt := p.errcnt
|
||||
body := p.blockStmt("")
|
||||
// p.fnest--
|
||||
if p.mode&CheckBranches != 0 {
|
||||
p.fnest--
|
||||
|
||||
// Don't check branches if there were syntax errors in the function
|
||||
// as it may lead to spurious errors (e.g., see test/switch2.go) or
|
||||
// possibly crashes due to incomplete syntax trees.
|
||||
if p.mode&CheckBranches != 0 && errcnt == p.errcnt {
|
||||
checkBranches(body, p.errh)
|
||||
}
|
||||
|
||||
return body
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue