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