Previously, reassigned was failing to detect reassignments due to
channel receives in select statements (OSELRECV, OSELRECV2), or due to
standalone 2-value receive assignments (OAS2RECV). This was reported
as a devirtualization panic, but could have caused mis-inlining as
well.
Fixes #43292.
Change-Id: Ic8079c20c0587aeacff9596697fdeba80a697b12
Reviewed-on: https://go-review.googlesource.com/c/go/+/279352
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
return nil
}
switch n.Op {
- case OAS:
+ case OAS, OSELRECV:
if n.Left == v.name && n != v.name.Name.Defn {
return n
}
- case OAS2, OAS2FUNC, OAS2MAPR, OAS2DOTTYPE:
+ case OAS2, OAS2FUNC, OAS2MAPR, OAS2DOTTYPE, OAS2RECV:
for _, p := range n.List.Slice() {
if p == v.name && n != v.name.Name.Defn {
return n
}
}
+ case OSELRECV2:
+ if (n.Left == v.name || n.List.First() == v.name) && n != v.name.Name.Defn {
+ return n
+ }
}
if a := v.visit(n.Left); a != nil {
return a
--- /dev/null
+// run
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func main() {
+ {
+ i := I(A{})
+
+ b := make(chan I, 1)
+ b <- B{}
+
+ var ok bool
+ i, ok = <-b
+ _ = ok
+
+ i.M()
+ }
+
+ {
+ i := I(A{})
+
+ b := make(chan I, 1)
+ b <- B{}
+
+ select {
+ case i = <-b:
+ }
+
+ i.M()
+ }
+
+ {
+ i := I(A{})
+
+ b := make(chan I, 1)
+ b <- B{}
+
+ var ok bool
+ select {
+ case i, ok = <-b:
+ }
+ _ = ok
+
+ i.M()
+ }
+}
+
+type I interface{ M() int }
+
+type T int
+
+func (T) M() int { return 0 }
+
+type A struct{ T }
+type B struct{ T }