Skip to content

Commit

Permalink
SA4000: add exceptions for functions from math/rand
Browse files Browse the repository at this point in the history
Closes gh-1087

(cherry picked from commit c4bd432)
  • Loading branch information
dominikh committed Nov 11, 2021
1 parent 40877a4 commit 2659add
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 0 deletions.
35 changes: 35 additions & 0 deletions staticcheck/lint.go
Original file line number Diff line number Diff line change
Expand Up @@ -1360,6 +1360,9 @@ func CheckLhsRhsIdentical(pass *analysis.Pass) (interface{}, error) {
// happily flags fn() == fn() – so far, we've had nobody complain
// about a false positive, and it's caught several bugs in real
// code.
//
// We special case functions from the math/rand package. Someone ran
// into the following false positive: "rand.Intn(2) - rand.Intn(2), which I wrote to generate values {-1, 0, 1} with {0.25, 0.5, 0.25} probability."
fn := func(node ast.Node) {
op := node.(*ast.BinaryExpr)
switch op.Op {
Expand Down Expand Up @@ -1399,6 +1402,38 @@ func CheckLhsRhsIdentical(pass *analysis.Pass) (interface{}, error) {
// 0 == 0 are slim.
return
}

if expr, ok := op.X.(*ast.CallExpr); ok {
call := code.CallName(pass, expr)
switch call {
case "math/rand.Int",
"math/rand.Int31",
"math/rand.Int31n",
"math/rand.Int63",
"math/rand.Int63n",
"math/rand.Intn",
"math/rand.Uint32",
"math/rand.Uint64",
"math/rand.ExpFloat64",
"math/rand.Float32",
"math/rand.Float64",
"math/rand.NormFloat64",
"(*math/rand.Rand).Int",
"(*math/rand.Rand).Int31",
"(*math/rand.Rand).Int31n",
"(*math/rand.Rand).Int63",
"(*math/rand.Rand).Int63n",
"(*math/rand.Rand).Intn",
"(*math/rand.Rand).Uint32",
"(*math/rand.Rand).Uint64",
"(*math/rand.Rand).ExpFloat64",
"(*math/rand.Rand).Float32",
"(*math/rand.Rand).Float64",
"(*math/rand.Rand).NormFloat64":
return
}
}

report.Report(pass, op, fmt.Sprintf("identical expressions on the left and right side of the '%s' operator", op.Op))
}
code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package pkg

import "math/rand"

type Float float64

type Floats [5]float64
Expand Down Expand Up @@ -65,3 +67,34 @@ func fn(a int, s []int, f1 float64, f2 Float, fs Floats, is Ints, t1 T1, t2 T2)
println()
}
}

func fn2() {
_ = rand.Int() - rand.Int()
_ = rand.Int31() - rand.Int31()
_ = rand.Int31n(0) - rand.Int31n(0)
_ = rand.Int63() - rand.Int63()
_ = rand.Int63n(0) - rand.Int63n(0)
_ = rand.Intn(0) - rand.Intn(0)
_ = rand.Uint32() - rand.Uint32()
_ = rand.Uint64() - rand.Uint64()
_ = rand.ExpFloat64() - rand.ExpFloat64()
_ = rand.Float32() - rand.Float32()
_ = rand.Float64() - rand.Float64()
_ = rand.NormFloat64() - rand.NormFloat64()

var rng *rand.Rand
_ = rng.Int() - rng.Int()
_ = rng.Int31() - rng.Int31()
_ = rng.Int31n(0) - rng.Int31n(0)
_ = rng.Int63() - rng.Int63()
_ = rng.Int63n(0) - rng.Int63n(0)
_ = rng.Intn(0) - rng.Intn(0)
_ = rng.Uint32() - rng.Uint32()
_ = rng.Uint64() - rng.Uint64()
_ = rng.ExpFloat64() - rng.ExpFloat64()
_ = rng.Float32() - rng.Float32()
_ = rng.Float64() - rng.Float64()
_ = rng.NormFloat64() - rng.NormFloat64()

_ = rand.NewSource(0) == rand.NewSource(0) // want `identical expressions`
}

0 comments on commit 2659add

Please sign in to comment.