summaryrefslogtreecommitdiff
path: root/libgo/go/cmd/vet/bool.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/cmd/vet/bool.go')
-rw-r--r--libgo/go/cmd/vet/bool.go29
1 files changed, 20 insertions, 9 deletions
diff --git a/libgo/go/cmd/vet/bool.go b/libgo/go/cmd/vet/bool.go
index 07c2a93dffa..1cd477f988c 100644
--- a/libgo/go/cmd/vet/bool.go
+++ b/libgo/go/cmd/vet/bool.go
@@ -31,7 +31,7 @@ func checkBool(f *File, n ast.Node) {
return
}
- comm := op.commutativeSets(e)
+ comm := op.commutativeSets(f, e)
for _, exprs := range comm {
op.checkRedundant(f, exprs)
op.checkSuspect(f, exprs)
@@ -53,14 +53,14 @@ var (
// expressions in e that are connected by op.
// For example, given 'a || b || f() || c || d' with the or op,
// commutativeSets returns {{b, a}, {d, c}}.
-func (op boolOp) commutativeSets(e *ast.BinaryExpr) [][]ast.Expr {
+func (op boolOp) commutativeSets(f *File, e *ast.BinaryExpr) [][]ast.Expr {
exprs := op.split(e)
// Partition the slice of expressions into commutative sets.
i := 0
var sets [][]ast.Expr
for j := 0; j <= len(exprs); j++ {
- if j == len(exprs) || hasSideEffects(exprs[j]) {
+ if j == len(exprs) || hasSideEffects(f, exprs[j]) {
if i < j {
sets = append(sets, exprs[i:j])
}
@@ -136,16 +136,27 @@ func (op boolOp) checkSuspect(f *File, exprs []ast.Expr) {
}
// hasSideEffects reports whether evaluation of e has side effects.
-func hasSideEffects(e ast.Expr) bool {
+func hasSideEffects(f *File, e ast.Expr) bool {
safe := true
ast.Inspect(e, func(node ast.Node) bool {
switch n := node.(type) {
- // Using CallExpr here will catch conversions
- // as well as function and method invocations.
- // We'll live with the false negatives for now.
case *ast.CallExpr:
- safe = false
- return false
+ typVal := f.pkg.types[n.Fun]
+ switch {
+ case typVal.IsType():
+ // Type conversion, which is safe.
+ case typVal.IsBuiltin():
+ // Builtin func, conservatively assumed to not
+ // be safe for now.
+ safe = false
+ return false
+ default:
+ // A non-builtin func or method call.
+ // Conservatively assume that all of them have
+ // side effects for now.
+ safe = false
+ return false
+ }
case *ast.UnaryExpr:
if n.Op == token.ARROW {
safe = false