github.com/amarpal/go-tools@v0.0.0-20240422043104-40142f59f616/staticcheck/sa4015/sa4015.go (about) 1 package sa4015 2 3 import ( 4 "fmt" 5 "go/types" 6 7 "github.com/amarpal/go-tools/analysis/callcheck" 8 "github.com/amarpal/go-tools/analysis/lint" 9 "github.com/amarpal/go-tools/go/ir" 10 "github.com/amarpal/go-tools/go/ir/irutil" 11 "github.com/amarpal/go-tools/internal/passes/buildir" 12 13 "golang.org/x/tools/go/analysis" 14 ) 15 16 var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{ 17 Analyzer: &analysis.Analyzer{ 18 Name: "SA4015", 19 Requires: []*analysis.Analyzer{buildir.Analyzer}, 20 Run: callcheck.Analyzer(checkMathIntRules), 21 }, 22 Doc: &lint.Documentation{ 23 Title: `Calling functions like \'math.Ceil\' on floats converted from integers doesn't do anything useful`, 24 Since: "2017.1", 25 Severity: lint.SeverityWarning, 26 MergeIf: lint.MergeIfAll, 27 }, 28 }) 29 30 var Analyzer = SCAnalyzer.Analyzer 31 32 var checkMathIntRules = map[string]callcheck.Check{ 33 "math.Ceil": pointlessIntMath, 34 "math.Floor": pointlessIntMath, 35 "math.IsNaN": pointlessIntMath, 36 "math.Trunc": pointlessIntMath, 37 "math.IsInf": pointlessIntMath, 38 } 39 40 func pointlessIntMath(call *callcheck.Call) { 41 if ConvertedFromInt(call.Args[0].Value) { 42 call.Invalid(fmt.Sprintf("calling %s on a converted integer is pointless", irutil.CallName(call.Instr.Common()))) 43 } 44 } 45 46 func ConvertedFromInt(v callcheck.Value) bool { 47 conv, ok := v.Value.(*ir.Convert) 48 if !ok { 49 return false 50 } 51 b, ok := conv.X.Type().Underlying().(*types.Basic) 52 if !ok { 53 return false 54 } 55 if (b.Info() & types.IsInteger) == 0 { 56 return false 57 } 58 return true 59 }