mirror of
https://github.com/golang/go
synced 2024-11-19 14:54:43 -07:00
go/parser: check presence of 2nd and 3rd index in 3-index slice
Fixes #7305. LGTM=adonovan R=bradfitz, adonovan CC=golang-codereviews https://golang.org/cl/58950045
This commit is contained in:
parent
85e4cb2f10
commit
13a5958db3
@ -1168,16 +1168,19 @@ func (p *parser) parseIndexOrSlice(x ast.Expr) ast.Expr {
|
||||
defer un(trace(p, "IndexOrSlice"))
|
||||
}
|
||||
|
||||
const N = 3 // change the 3 to 2 to disable 3-index slices
|
||||
lbrack := p.expect(token.LBRACK)
|
||||
p.exprLev++
|
||||
var index [3]ast.Expr // change the 3 to 2 to disable slice expressions w/ cap
|
||||
var index [N]ast.Expr
|
||||
var colons [N - 1]token.Pos
|
||||
if p.tok != token.COLON {
|
||||
index[0] = p.parseRhs()
|
||||
}
|
||||
ncolons := 0
|
||||
for p.tok == token.COLON && ncolons < len(index)-1 {
|
||||
p.next()
|
||||
for p.tok == token.COLON && ncolons < len(colons) {
|
||||
colons[ncolons] = p.pos
|
||||
ncolons++
|
||||
p.next()
|
||||
if p.tok != token.COLON && p.tok != token.RBRACK && p.tok != token.EOF {
|
||||
index[ncolons] = p.parseRhs()
|
||||
}
|
||||
@ -1187,7 +1190,21 @@ func (p *parser) parseIndexOrSlice(x ast.Expr) ast.Expr {
|
||||
|
||||
if ncolons > 0 {
|
||||
// slice expression
|
||||
return &ast.SliceExpr{X: x, Lbrack: lbrack, Low: index[0], High: index[1], Max: index[2], Slice3: ncolons == 2, Rbrack: rbrack}
|
||||
slice3 := false
|
||||
if ncolons == 2 {
|
||||
slice3 = true
|
||||
// Check presence of 2nd and 3rd index here rather than during type-checking
|
||||
// to prevent erroneous programs from passing through gofmt (was issue 7305).
|
||||
if index[1] == nil {
|
||||
p.error(colons[0], "2nd index required in 3-index slice")
|
||||
index[1] = &ast.BadExpr{From: colons[0] + 1, To: colons[1]}
|
||||
}
|
||||
if index[2] == nil {
|
||||
p.error(colons[1], "3rd index required in 3-index slice")
|
||||
index[2] = &ast.BadExpr{From: colons[1] + 1, To: rbrack}
|
||||
}
|
||||
}
|
||||
return &ast.SliceExpr{X: x, Lbrack: lbrack, Low: index[0], High: index[1], Max: index[2], Slice3: slice3, Rbrack: rbrack}
|
||||
}
|
||||
|
||||
return &ast.IndexExpr{X: x, Lbrack: lbrack, Index: index[0], Rbrack: rbrack}
|
||||
|
@ -76,7 +76,11 @@ var invalids = []string{
|
||||
`package p; func f() { _ = x = /* ERROR "expected '=='" */ 0 {}};`,
|
||||
`package p; func f() { _ = 1 == func()int { var x bool; x = x = /* ERROR "expected '=='" */ true; return x }() };`,
|
||||
`package p; func f() { var s []int; _ = s[] /* ERROR "expected operand" */ };`,
|
||||
`package p; func f() { var s []int; _ = s[::: /* ERROR "expected ']'" */ ] };`,
|
||||
`package p; func f() { var s []int; _ = s[i:j: /* ERROR "3rd index required" */ ] };`,
|
||||
`package p; func f() { var s []int; _ = s[i: /* ERROR "2nd index required" */ :k] };`,
|
||||
`package p; func f() { var s []int; _ = s[i: /* ERROR "2nd index required" */ :] };`,
|
||||
`package p; func f() { var s []int; _ = s[: /* ERROR "2nd index required" */ :] };`,
|
||||
`package p; func f() { var s []int; _ = s[: /* ERROR "2nd index required" */ ::] };`,
|
||||
`package p; func f() { var s []int; _ = s[i:j:k: /* ERROR "expected ']'" */ l] };`,
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user