]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.regabi] cmd/compile: cleanup type switch typechecking
authorMatthew Dempsky <mdempsky@google.com>
Mon, 16 Nov 2020 16:44:40 +0000 (08:44 -0800)
committerMatthew Dempsky <mdempsky@google.com>
Tue, 24 Nov 2020 19:32:42 +0000 (19:32 +0000)
Address outstanding TODO, which simplifies subsequent CLs.

Now the compiler always type checks type-switch case clauses (like
gccgo), but it treats clause variables as broken if an appropriate
type cannot be determined for it (like go/types).

Passes toolstash-check.

Change-Id: Iedfe9cdf38c6865211e4b93391f1cf72c1bed136
Reviewed-on: https://go-review.googlesource.com/c/go/+/272648
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
Trust: Matthew Dempsky <mdempsky@google.com>

src/cmd/compile/internal/gc/swt.go
test/fixedbugs/bug340.go

index 9205f4142a0e7c7e52528ab409be4aebf0b3a34c..9ab5f0c2487e1c9681b043778aaade00c67bac70 100644 (file)
@@ -89,22 +89,22 @@ func typecheckTypeSwitch(n *Node) {
                        if len(ls) == 1 {
                                if ls[0].Op == OTYPE {
                                        vt = ls[0].Type
-                               } else if ls[0].Op != OLITERAL { // TODO(mdempsky): Should be !ls[0].isNil()
+                               } else if !ls[0].isNil() {
                                        // Invalid single-type case;
                                        // mark variable as broken.
                                        vt = nil
                                }
                        }
 
-                       // TODO(mdempsky): It should be possible to
-                       // still typecheck the case body.
-                       if vt == nil {
-                               continue
-                       }
-
                        nvar := ncase.Rlist.First()
                        nvar.Type = vt
-                       nvar = typecheck(nvar, ctxExpr|ctxAssign)
+                       if vt != nil {
+                               nvar = typecheck(nvar, ctxExpr|ctxAssign)
+                       } else {
+                               // Clause variable is broken; prevent typechecking.
+                               nvar.SetTypecheck(1)
+                               nvar.SetWalkdef(1)
+                       }
                        ncase.Rlist.SetFirst(nvar)
                }
 
index 118bbacc2202e9563a82034538fc2f5624be0fce..a0679404089206bee1e49ce22acb30c276474955 100644 (file)
@@ -12,6 +12,7 @@ func main() {
        var x interface{}
        switch t := x.(type) {
        case 0:         // ERROR "type"
-               t.x = 1 // ERROR "type interface \{\}|reference to undefined field or method"
+               t.x = 1
+               x.x = 1 // ERROR "type interface \{\}|reference to undefined field or method"
        }
 }