]> Cypherpunks repositories - gostls13.git/commitdiff
go/parser: check presence of 2nd and 3rd index in 3-index slice
authorRobert Griesemer <gri@golang.org>
Tue, 11 Feb 2014 21:40:37 +0000 (13:40 -0800)
committerRobert Griesemer <gri@golang.org>
Tue, 11 Feb 2014 21:40:37 +0000 (13:40 -0800)
Fixes #7305.

LGTM=adonovan
R=bradfitz, adonovan
CC=golang-codereviews
https://golang.org/cl/58950045

src/pkg/go/parser/parser.go
src/pkg/go/parser/short_test.go

index d8cde99de2347bc539054d3df39a74f1a8467e87..2ad3e4e55610974c904c9cb01c3b625b33477e30 100644 (file)
@@ -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}
index 0ef0c560c4a50d95be87d4c7d2012959c74dd04e..9d18d049000c9f22372b71e2df28c83d772a3c49 100644 (file)
@@ -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] };`,
 }