]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.regabi] cmd/compile: make ir.OuterValue safer
authorMatthew Dempsky <mdempsky@google.com>
Tue, 5 Jan 2021 11:28:06 +0000 (03:28 -0800)
committerMatthew Dempsky <mdempsky@google.com>
Tue, 5 Jan 2021 14:03:51 +0000 (14:03 +0000)
For OINDEX expressions, ir.OuterValue depends on knowing the indexee's
type. Rather than silently acting as though it's not an array, make it
loudly fail.

The only code that needs to be fixed to support this is checkassign
during typechecking, which needs to avoid calling ir.OuterValue now if
typechecking the assigned operand already failed.

Passes toolstash -cmp.

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

index a5a7203faaa22d7474781dbb07044d46ba68b79f..850d7343aaef189ff8f96505172e27577986ce23 100644 (file)
@@ -568,7 +568,10 @@ func OuterValue(n Node) Node {
                        continue
                case OINDEX:
                        nn := nn.(*IndexExpr)
-                       if nn.X.Type() != nil && nn.X.Type().IsArray() {
+                       if nn.X.Type() == nil {
+                               base.Fatalf("OuterValue needs type for %v", nn.X)
+                       }
+                       if nn.X.Type().IsArray() {
                                n = nn.X
                                continue
                        }
index 981f4ef1d6efd11d932554081c72252e133d7744..c3a5a3c40f715cc7b177f914ec8f4e60ee7dc832 100644 (file)
@@ -1612,6 +1612,14 @@ func checklvalue(n ir.Node, verb string) {
 }
 
 func checkassign(stmt ir.Node, n ir.Node) {
+       // have already complained about n being invalid
+       if n.Type() == nil {
+               if base.Errors() == 0 {
+                       base.Fatalf("expected an error about %v", n)
+               }
+               return
+       }
+
        // Variables declared in ORANGE are assigned on every iteration.
        if !ir.DeclaredBy(n, stmt) || stmt.Op() == ir.ORANGE {
                r := ir.OuterValue(n)
@@ -1633,11 +1641,6 @@ func checkassign(stmt ir.Node, n ir.Node) {
                return
        }
 
-       // have already complained about n being invalid
-       if n.Type() == nil {
-               return
-       }
-
        switch {
        case n.Op() == ir.ODOT && n.(*ir.SelectorExpr).X.Op() == ir.OINDEXMAP:
                base.Errorf("cannot assign to struct field %v in map", n)