]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: move validation from unary/binaryOp to typecheck
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Thu, 17 Sep 2020 15:53:39 +0000 (22:53 +0700)
committerCuong Manh Le <cuong.manhle.vn@gmail.com>
Fri, 18 Sep 2020 04:03:49 +0000 (04:03 +0000)
CL 254400 makes typecheck set untyped type correctly. We now have enough
information to check valid operators for a type in typecheck.

Passes toolstash-check.

Change-Id: I01a7606ee6ce9964ec52430d53eaa886442bd17f
Reviewed-on: https://go-review.googlesource.com/c/go/+/255617
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/gc/const.go
src/cmd/compile/internal/gc/typecheck.go

index 59b2c56051ad549ff33bc76979942eddf1b4caa7..399d0148bb056e454b594f4d8012e1c7fbc1e1c8 100644 (file)
@@ -838,10 +838,6 @@ Outer:
                                return Val{}
                        }
                        u.Quo(y)
-               case OMOD, OOR, OAND, OANDNOT, OXOR:
-                       // TODO(mdempsky): Move to typecheck; see #31060.
-                       yyerror("invalid operation: operator %v not defined on untyped float", op)
-                       return Val{}
                default:
                        break Outer
                }
@@ -867,10 +863,6 @@ Outer:
                                yyerror("complex division by zero")
                                return Val{}
                        }
-               case OMOD, OOR, OAND, OANDNOT, OXOR:
-                       // TODO(mdempsky): Move to typecheck; see #31060.
-                       yyerror("invalid operation: operator %v not defined on untyped complex", op)
-                       return Val{}
                default:
                        break Outer
                }
@@ -932,15 +924,6 @@ func unaryOp(op Op, x Val, t *types.Type) Val {
                        }
                        u.Xor(x)
                        return Val{U: u}
-
-               case CTFLT:
-                       // TODO(mdempsky): Move to typecheck; see #31060.
-                       yyerror("invalid operation: operator %v not defined on untyped float", op)
-                       return Val{}
-               case CTCPLX:
-                       // TODO(mdempsky): Move to typecheck; see #31060.
-                       yyerror("invalid operation: operator %v not defined on untyped complex", op)
-                       return Val{}
                }
 
        case ONOT:
@@ -1120,7 +1103,7 @@ func ctype(t *types.Type) Ctype {
 }
 
 func defaultType(t *types.Type) *types.Type {
-       if !t.IsUntyped() {
+       if !t.IsUntyped() || t.Etype == TNIL {
                return t
        }
 
index 274787a22bf37a1d91e7bfa28d358de1b066ef77..faa13d72f98a4ba94788b9de62b0a21c2397183b 100644 (file)
@@ -716,8 +716,22 @@ func typecheck1(n *Node, top int) (res *Node) {
                        }
                }
 
-               if !okfor[op][et] {
-                       yyerror("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(t))
+               if t.Etype == TIDEAL {
+                       switch {
+                       case l.Type == types.Idealcomplex || r.Type == types.Idealcomplex:
+                               t = types.Idealcomplex
+                       case l.Type == types.Idealfloat || r.Type == types.Idealfloat:
+                               t = types.Idealfloat
+                       case l.Type == types.Idealrune || r.Type == types.Idealrune:
+                               t = types.Idealrune
+                       case l.Type == types.Idealint || r.Type == types.Idealint:
+                               t = types.Idealint
+                       default:
+                               Fatalf("bad untyped type: %v", t)
+                       }
+               }
+               if dt := defaultType(t); !okfor[op][dt.Etype] {
+                       yyerror("invalid operation: %v (operator %v not defined on %v)", n, op, t)
                        n.Type = nil
                        return n
                }
@@ -756,15 +770,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                        }
                }
 
-               t = l.Type
                if iscmp[n.Op] {
-                       // TIDEAL includes complex constant, but only OEQ and ONE are defined for complex,
-                       // so check that the n.op is available for complex  here before doing evconst.
-                       if !okfor[n.Op][TCOMPLEX128] && (Isconst(l, CTCPLX) || Isconst(r, CTCPLX)) {
-                               yyerror("invalid operation: %v (operator %v not defined on untyped complex)", n, n.Op)
-                               n.Type = nil
-                               return n
-                       }
                        evconst(n)
                        t = types.Idealbool
                        if n.Op != OLITERAL {
@@ -801,20 +807,6 @@ func typecheck1(n *Node, top int) (res *Node) {
                }
 
                n.Type = t
-               if t.Etype == TIDEAL {
-                       switch {
-                       case l.Type == types.Idealcomplex || r.Type == types.Idealcomplex:
-                               n.Type = types.Idealcomplex
-                       case l.Type == types.Idealfloat || r.Type == types.Idealfloat:
-                               n.Type = types.Idealfloat
-                       case l.Type == types.Idealrune || r.Type == types.Idealrune:
-                               n.Type = types.Idealrune
-                       case l.Type == types.Idealint || r.Type == types.Idealint:
-                               n.Type = types.Idealint
-                       default:
-                               Fatalf("bad untyped type: %v", t)
-                       }
-               }
 
        case OBITNOT, ONEG, ONOT, OPLUS:
                ok |= ctxExpr
@@ -825,8 +817,8 @@ func typecheck1(n *Node, top int) (res *Node) {
                        n.Type = nil
                        return n
                }
-               if !okfor[n.Op][t.Etype] {
-                       yyerror("invalid operation: %v %v", n.Op, t)
+               if !okfor[n.Op][defaultType(t).Etype] {
+                       yyerror("invalid operation: %v (operator %v not defined on %s)", n, n.Op, typekind(t))
                        n.Type = nil
                        return n
                }