Commit 68e39030 authored by griesemer's avatar griesemer Committed by Robert Griesemer

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: 's avatarMatthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 39edffb6
......@@ -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
}
......
......@@ -50,7 +50,10 @@ func f() {
labelname: // ERROR "missing statement after label"
case false:
}
}
func g() {
var z bool
switch {
case z:
labelname: // ERROR "label labelname defined and not used"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment