]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/noder: fix type switch case vars package
authorMatthew Dempsky <mdempsky@google.com>
Wed, 7 Sep 2022 02:30:30 +0000 (19:30 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Wed, 7 Sep 2022 17:26:39 +0000 (17:26 +0000)
When naming case variables, the unified frontend was using
typecheck.Lookup, which uses the current package, rather than
localIdent, which uses the package the variable was originally
declared in. When inlining across package boundaries, this could cause
the case variables to be associated with the wrong package.

In practice, I don't believe this has any negative consequences, but
it's inconsistent and triggered an ICE in typecheck.ClosureType, which
expected all captured variables to be declared in the same package.

Easy fix is to ensure case variables are declared in the correct
package by using localIdent.

Fixes #54912.

Change-Id: I7a429c708ad95723f46a67872cb0cf0c53a6a0d6
Reviewed-on: https://go-review.googlesource.com/c/go/+/428918
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Benny Siegert <bsiegert@gmail.com>
src/cmd/compile/internal/noder/reader.go
src/cmd/compile/internal/noder/writer.go
src/cmd/compile/internal/typecheck/func.go
test/run.go

index fb9df3284fa7bf59c3f25fda832c29e05da82918..b8df7c9773424d933fe2ad7e42aa5f3fef9101e1 100644 (file)
@@ -1957,7 +1957,7 @@ func (r *reader) switchStmt(label *types.Sym) ir.Node {
                pos := r.pos()
                if r.Bool() {
                        pos := r.pos()
-                       sym := typecheck.Lookup(r.String())
+                       _, sym := r.localIdent()
                        ident = ir.NewIdent(pos, sym)
                }
                x := r.expr()
index 0b1d41d7501d104efe8993a97ae2f330668efc48..198bae71903da00b8b9b744dd2a0fa52ff35cadc 100644 (file)
@@ -1484,6 +1484,10 @@ func (w *writer) switchStmt(stmt *syntax.SwitchStmt) {
                w.pos(guard)
                if tag := guard.Lhs; w.Bool(tag != nil) {
                        w.pos(tag)
+
+                       // Like w.localIdent, but we don't have a types2.Object.
+                       w.Sync(pkgbits.SyncLocalIdent)
+                       w.pkg(w.p.curpkg)
                        w.String(tag.Value)
                }
                w.expr(guard.X)
index d62066f33ce8e121520d731fbf37089318e5dd1e..7cf9d5cb404f904f4bbf74e576a6ba1a80c6d446 100644 (file)
@@ -105,7 +105,7 @@ func ClosureType(clo *ir.ClosureExpr) *types.Type {
                        if pkg == nil {
                                pkg = v.Sym().Pkg
                        } else if pkg != v.Sym().Pkg {
-                               base.Fatalf("Closure variables from multiple packages")
+                               base.Fatalf("Closure variables from multiple packages: %+v", clo)
                        }
                }
        }
index ecb08ce83496fcf20d601be384ddd406027247f6..3c5b10ad32c46d7e32fb8518f6986c974ed713c1 100644 (file)
@@ -2021,8 +2021,6 @@ var unifiedFailures = setOf(
        "closure3.go", // unified IR numbers closures differently than -d=inlfuncswithclosures
        "escape4.go",  // unified IR can inline f5 and f6; test doesn't expect this
 
-       "fixedbugs/issue54912.go", // ICE when inlined type switch case variable captured in function literal
-
        "typeparam/issue47631.go", // unified IR can handle local type declarations
 )