base.Fatalf("RHS is nil: %v", defn)
}
- if reassigned(n) {
+ if Reassigned(n) {
return nil
}
return rhs
}
-// reassigned takes an ONAME node, walks the function in which it is defined, and returns a boolean
-// indicating whether the name has any assignments other than its declaration.
-// The second return value is the first such assignment encountered in the walk, if any. It is mostly
-// useful for -m output documenting the reason for inhibited optimizations.
+// Reassigned takes an ONAME node, walks the function in which it is
+// defined, and returns a boolean indicating whether the name has any
+// assignments other than its declaration.
// NB: global variables are always considered to be re-assigned.
-// TODO: handle initial declaration not including an assignment and followed by a single assignment?
-func reassigned(name *Name) bool {
+// TODO: handle initial declaration not including an assignment and
+// followed by a single assignment?
+func Reassigned(name *Name) bool {
if name.Op() != ONAME {
base.Fatalf("reassigned %v", name)
}
// isName reports whether n is a reference to name.
isName := func(x Node) bool {
- n, ok := x.(*Name)
+ if x == nil {
+ return false
+ }
+ n, ok := OuterValue(x).(*Name)
return ok && n.Canonical() == name
}
return true
}
}
+ case OASOP:
+ n := n.(*AssignOpStmt)
+ if isName(n.X) {
+ return true
+ }
case OADDR:
n := n.(*AddrExpr)
- if isName(OuterValue(n.X)) {
+ if isName(n.X) {
return true
}
case ORANGE: