Skip to content

go/parser: goto; is incorrectly valid #70957

Open
@mateusz834

Description

While poking around the go/types internals, i noticed that nothing really "type-checks" gotos without labels.

First pass:

go/src/go/types/stmt.go

Lines 578 to 608 in 500675a

case *ast.BranchStmt:
if s.Label != nil {
check.hasLabel = true
return // checked in 2nd pass (check.labels)
}
switch s.Tok {
case token.BREAK:
if ctxt&breakOk == 0 {
check.error(s, MisplacedBreak, "break not in for, switch, or select statement")
}
case token.CONTINUE:
if ctxt&continueOk == 0 {
check.error(s, MisplacedContinue, "continue not in for statement")
}
case token.FALLTHROUGH:
if ctxt&fallthroughOk == 0 {
var msg string
switch {
case ctxt&finalSwitchCase != 0:
msg = "cannot fallthrough final case in switch"
case ctxt&inTypeSwitch != 0:
msg = "cannot fallthrough in type switch"
default:
msg = "fallthrough statement out of place"
}
check.error(s, MisplacedFallthrough, msg)
}
default:
check.errorf(s, InvalidSyntaxTree, "branch statement: %s", s.Tok)
}

Second pass:

go/src/go/types/labels.go

Lines 173 to 176 in 500675a

case *ast.BranchStmt:
if s.Label == nil {
return // checked in 1st pass (check.stmt)
}

Also it also turns out that:

func test() {
    goto;
}

Is accepted by the go/parser. The spec disallows gotos without labels, so we should either return an appropriate error in go/types or go/parser. Currently go/types returns an InvalidSyntaxTree error.

go/src/go/types/stmt.go

Lines 605 to 607 in 500675a

default:
check.errorf(s, InvalidSyntaxTree, "branch statement: %s", s.Tok)
}

CC @griesemer @adonovan

Metadata

Assignees

Labels

NeedsFixThe path to resolution is known, but the work has not been done.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions