]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: better error message for certain unary/binary expression errors
authorRobert Griesemer <gri@golang.org>
Tue, 23 Jun 2015 20:59:18 +0000 (13:59 -0700)
committerRobert Griesemer <gri@golang.org>
Tue, 23 Jun 2015 21:05:46 +0000 (21:05 +0000)
Port of https://go-review.googlesource.com/11363.

Fixes #11367.

Change-Id: Ie0a82bcfab782c514d1947e7a6b190e286afd159
Reviewed-on: https://go-review.googlesource.com/11367
Reviewed-by: Alan Donovan <adonovan@google.com>
src/go/types/expr.go
src/go/types/stmt.go
src/go/types/testdata/expr0.src

index e9baf93aeb687685d90842eeebb4814ec6cb8cb4..63a014a92934c737d6bb6c12df557fc03957fdbb 100644 (file)
@@ -78,7 +78,8 @@ func (check *Checker) op(m opPredicates, x *operand, op token.Token) bool {
        return true
 }
 
-func (check *Checker) unary(x *operand, op token.Token) {
+// The unary expression e may be nil. It's passed in for better error messages only.
+func (check *Checker) unary(x *operand, e *ast.UnaryExpr, op token.Token) {
        switch op {
        case token.AND:
                // spec: "As an exception to the addressability
@@ -125,6 +126,9 @@ func (check *Checker) unary(x *operand, op token.Token) {
                // Typed constants must be representable in
                // their type after each constant operation.
                if isTyped(typ) {
+                       if e != nil {
+                               x.expr = e // for better error message
+                       }
                        check.representable(x, typ)
                }
                return
@@ -721,7 +725,8 @@ var binaryOpPredicates = opPredicates{
        token.LOR:  isBoolean,
 }
 
-func (check *Checker) binary(x *operand, lhs, rhs ast.Expr, op token.Token) {
+// The binary expression e may be nil. It's passed in for better error messages only.
+func (check *Checker) binary(x *operand, e *ast.BinaryExpr, lhs, rhs ast.Expr, op token.Token) {
        var y operand
 
        check.expr(x, lhs)
@@ -787,6 +792,9 @@ func (check *Checker) binary(x *operand, lhs, rhs ast.Expr, op token.Token) {
                // Typed constants must be representable in
                // their type after each constant operation.
                if isTyped(typ) {
+                       if e != nil {
+                               x.expr = e // for better error message
+                       }
                        check.representable(x, typ)
                }
                return
@@ -1374,7 +1382,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
                if x.mode == invalid {
                        goto Error
                }
-               check.unary(x, e.Op)
+               check.unary(x, e, e.Op)
                if x.mode == invalid {
                        goto Error
                }
@@ -1384,7 +1392,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
                }
 
        case *ast.BinaryExpr:
-               check.binary(x, e.X, e.Y, e.Op)
+               check.binary(x, e, e.X, e.Y, e.Op)
                if x.mode == invalid {
                        goto Error
                }
index 6efe86c9f87d3615f0467744b72831f79fc07915..7fdcb7925c95dca2ca4c5de3ff088ba7d810d305 100644 (file)
@@ -277,7 +277,7 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
                }
                var x operand
                Y := &ast.BasicLit{ValuePos: s.X.Pos(), Kind: token.INT, Value: "1"} // use x's position
-               check.binary(&x, s.X, Y, op)
+               check.binary(&x, nil, s.X, Y, op)
                if x.mode == invalid {
                        return
                }
@@ -309,7 +309,7 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
                                return
                        }
                        var x operand
-                       check.binary(&x, s.Lhs[0], s.Rhs[0], op)
+                       check.binary(&x, nil, s.Lhs[0], s.Rhs[0], op)
                        if x.mode == invalid {
                                return
                        }
index 5afb5d738e466d6e9007a0bac7a13f2744a93aa2..3120c6f0781aabf2be14fa926d225cef793ac93a 100644 (file)
@@ -25,6 +25,12 @@ var (
        b12 = <-b0 /* ERROR "cannot receive" */
        b13 = & & /* ERROR "cannot take address" */ b0
 
+       // byte
+       _ = byte(0)
+       _ = byte(- /* ERROR "cannot convert" */ 1)
+       _ = - /* ERROR "-byte\(1\) \(constant -1 of type byte\) overflows byte" */ byte(1) // test for issue 11367
+       _ = byte /* ERROR "overflows byte" */ (0) - byte(1)
+
        // int
        i0 = 1
        i1 int = i0