// conversion as a *types.Named.
typVal := f.pkg.types[n.Fun]
_, isSig := typVal.Type.(*types.Signature)
- if typVal.IsValue() && isSig {
+ switch {
+ case typVal.IsValue() && isSig:
// If we have a value of unnamed signature type,
- // this CallExpr is a func call and not a type
- // conversion. Conservatively assume that all
- // function and method calls have side effects
- // for now.
+ // this CallExpr is a non-builtin func call and
+ // not a type conversion. Conservatively assume
+ // that all function and method calls have side
+ // effects for now.
+ safe = false
+ return false
+ case typVal.IsBuiltin():
+ // For now, conservatively assume that all
+ // built-in functions have side effects.
safe = false
return false
}
type T int
+func (t T) Foo() int { return int(t) }
+
type FT func() int
+var S []int
+
func RatherStupidConditions() {
var f, g func() int
if f() == 0 || f() == 0 { // OK f might have side effects
}
+ var t T
+ _ = t.Foo() == 2 || t.Foo() == 2 // OK Foo might have side effects
if v, w := f(), g(); v == w || v == w { // ERROR "redundant or: v == w || v == w"
}
_ = f == nil || f == nil // ERROR "redundant or: f == nil || f == nil"
_ = FT(f) == nil || FT(f) == nil // ERROR "redundant or: FT(f) == nil || FT(f) == nil"
_ = (func() int)(f) == nil || (func() int)(f) == nil // ERROR "redundant or: (func() int)(f) == nil || (func() int)(f) == nil"
+ _ = append(S, 3) == nil || append(S, 3) == nil // OK append has side effects
var namedFuncVar FT
- _ = namedFuncVar() == namedFuncVar() // OK; still func calls
+ _ = namedFuncVar() == namedFuncVar() // OK still func calls
var c chan int
_ = 0 == <-c || 0 == <-c // OK subsequent receives may yield different values