]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: fixed a few failure checks
authorRobert Griesemer <gri@golang.org>
Sat, 2 Mar 2013 01:39:22 +0000 (17:39 -0800)
committerRobert Griesemer <gri@golang.org>
Sat, 2 Mar 2013 01:39:22 +0000 (17:39 -0800)
More robustness in case of incorrect programs.

Fixes #4962.

R=dsymonds
CC=golang-dev
https://golang.org/cl/7429047

src/pkg/go/types/expr.go
src/pkg/go/types/stmt.go

index f54b6252b6dde29cad04c7540a90a616a130d5bc..86d782d483621271e244860e14a7dcd8946aeee9 100644 (file)
@@ -550,6 +550,15 @@ func (check *checker) binary(x *operand, lhs, rhs ast.Expr, op token.Token, iota
        check.expr(x, lhs, nil, iota)
        check.expr(&y, rhs, nil, iota)
 
+       if x.mode == invalid {
+               return
+       }
+       if y.mode == invalid {
+               x.mode = invalid
+               x.expr = y.expr
+               return
+       }
+
        if isShift(op) {
                check.shift(x, &y, op)
                return
@@ -1089,6 +1098,9 @@ func (check *checker) rawExpr(x *operand, e ast.Expr, hint Type, iota int, cycle
 
        case *ast.IndexExpr:
                check.expr(x, e.X, nil, iota)
+               if x.mode == invalid {
+                       goto Error
+               }
 
                valid := false
                length := int64(-1) // valid if >= 0
@@ -1130,9 +1142,9 @@ func (check *checker) rawExpr(x *operand, e ast.Expr, hint Type, iota int, cycle
                case *Map:
                        var key operand
                        check.expr(&key, e.Index, nil, iota)
-                       if key.mode == invalid || !check.assignment(&key, typ.Key) {
-                               if x.mode != invalid {
-                                       check.invalidOp(x.pos(), "cannot use %s as map index of type %s", &key, typ.Key)
+                       if !check.assignment(&key, typ.Key) {
+                               if key.mode != invalid {
+                                       check.invalidOp(key.pos(), "cannot use %s as map index of type %s", &key, typ.Key)
                                }
                                goto Error
                        }
@@ -1157,6 +1169,9 @@ func (check *checker) rawExpr(x *operand, e ast.Expr, hint Type, iota int, cycle
 
        case *ast.SliceExpr:
                check.expr(x, e.X, nil, iota)
+               if x.mode == invalid {
+                       goto Error
+               }
 
                valid := false
                length := int64(-1) // valid if >= 0
@@ -1367,10 +1382,19 @@ func (check *checker) rawExpr(x *operand, e ast.Expr, hint Type, iota int, cycle
 
        case *ast.UnaryExpr:
                check.expr(x, e.X, nil, iota)
+               if x.mode == invalid {
+                       goto Error
+               }
                check.unary(x, e.Op)
+               if x.mode == invalid {
+                       goto Error
+               }
 
        case *ast.BinaryExpr:
                check.binary(x, e.X, e.Y, e.Op, iota)
+               if x.mode == invalid {
+                       goto Error
+               }
 
        case *ast.KeyValueExpr:
                // key:value expressions are handled in composite literals
@@ -1423,7 +1447,9 @@ func (check *checker) rawExpr(x *operand, e ast.Expr, hint Type, iota int, cycle
                x.typ = &Chan{Dir: e.Dir, Elt: check.typ(e.Value, true)}
 
        default:
-               check.dump("e = %s", e)
+               if debug {
+                       check.dump("expr = %v (%T)", e, e)
+               }
                unreachable()
        }
 
index f4c158da91fa7358b21965cb2781b3914a7a23b6..53c46a167cd6be63db86645e7fc8b816bdc5abb9 100644 (file)
@@ -18,6 +18,10 @@ import (
 // TODO(gri) This latter behavior is for historic reasons and complicates
 // callers. Needs to be cleaned up.
 func (check *checker) assignment(x *operand, to Type) bool {
+       if x.mode == invalid {
+               return false
+       }
+
        if t, ok := x.typ.(*Result); ok {
                // TODO(gri) elsewhere we use "assignment count mismatch" (consolidate)
                check.errorf(x.pos(), "%d-valued expression %s used as single value", len(t.Values), x)