├── go.mod ├── main.go ├── analyzer ├── testdata │ └── src │ │ ├── with-fiximports │ │ ├── f.go.golden │ │ ├── f.go │ │ ├── e.go.golden │ │ ├── a.go │ │ ├── e.go │ │ ├── b.go │ │ ├── g.go │ │ ├── g.go.golden │ │ ├── b.go.golden │ │ ├── a.go.golden │ │ ├── c.go │ │ ├── d.go │ │ ├── d.go.golden │ │ └── c.go.golden │ │ ├── with-concat-loop │ │ ├── p.go │ │ └── p.go.golden │ │ ├── without-integer-format │ │ ├── p.go.golden │ │ └── p.go │ │ ├── without-int-conversion │ │ ├── p.go │ │ └── p.go.golden │ │ ├── without-string-format │ │ ├── p.go │ │ └── p.go.golden │ │ ├── without-bool-format │ │ ├── p.go │ │ └── p.go.golden │ │ ├── without-hex-format │ │ └── p.go │ │ ├── without-strconcat │ │ └── p.go │ │ └── without-sprintf1 │ │ └── p.go ├── diagnostic.go ├── analyzer_test.go └── replacements_bench_test.go ├── .golangci.yaml ├── Makefile ├── go.sum ├── .github └── workflows │ └── ci.yml ├── LICENSE └── README.md /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/catenacyber/perfsprint 2 | 3 | go 1.24.0 4 | 5 | require golang.org/x/tools v0.37.0 6 | 7 | require ( 8 | golang.org/x/mod v0.28.0 // indirect 9 | golang.org/x/sync v0.17.0 // indirect 10 | ) 11 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/catenacyber/perfsprint/analyzer" 5 | 6 | "golang.org/x/tools/go/analysis/singlechecker" 7 | ) 8 | 9 | func main() { 10 | singlechecker.Main(analyzer.New()) 11 | } 12 | -------------------------------------------------------------------------------- /analyzer/testdata/src/with-fiximports/f.go.golden: -------------------------------------------------------------------------------- 1 | package a 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func fmtf() { 8 | // fmt still used after removal 9 | fmt.Printf("Hello, World!", "toto") // want "string-format: fmt.Sprintf can be replaced with just using the string" 10 | } 11 | -------------------------------------------------------------------------------- /analyzer/testdata/src/with-fiximports/f.go: -------------------------------------------------------------------------------- 1 | package a 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func fmtf() { 8 | // fmt still used after removal 9 | fmt.Printf("Hello, World!", fmt.Sprintf("%s", "toto")) // want "string-format: fmt.Sprintf can be replaced with just using the string" 10 | } 11 | -------------------------------------------------------------------------------- /analyzer/testdata/src/with-fiximports/e.go.golden: -------------------------------------------------------------------------------- 1 | package a 2 | 3 | import ( 4 | // want "fiximports: Fix imports" 5 | ) 6 | 7 | func fmte() { 8 | // fmt removed as only import 9 | println("Hello, World!", "toto") // want "string-format: fmt.Sprintf can be replaced with just using the string" 10 | } 11 | -------------------------------------------------------------------------------- /analyzer/testdata/src/with-fiximports/a.go: -------------------------------------------------------------------------------- 1 | package a 2 | 3 | func loopconcat() { // want "fiximports: Fix imports" 4 | // no imports, adding strings 5 | s := "" 6 | for i := 0; i < 10; i++ { 7 | s += "toto" // want "concat-loop: string concatenation in a loop" 8 | } 9 | println("Hello, World!", s) 10 | } 11 | -------------------------------------------------------------------------------- /analyzer/testdata/src/with-fiximports/e.go: -------------------------------------------------------------------------------- 1 | package a 2 | 3 | import ( 4 | "fmt" // want "fiximports: Fix imports" 5 | ) 6 | 7 | func fmte() { 8 | // fmt removed as only import 9 | println("Hello, World!", fmt.Sprintf("%s", "toto")) // want "string-format: fmt.Sprintf can be replaced with just using the string" 10 | } 11 | -------------------------------------------------------------------------------- /analyzer/testdata/src/with-fiximports/b.go: -------------------------------------------------------------------------------- 1 | package a 2 | 3 | import ( 4 | "strings" 5 | ) 6 | 7 | func loopconcat2() { 8 | // already strings 9 | s := "" 10 | for i := 0; i < 10; i++ { 11 | s += "toto" // want "concat-loop: string concatenation in a loop" 12 | } 13 | println("Hello, World!", strings.Fields(s)) 14 | } 15 | -------------------------------------------------------------------------------- /analyzer/testdata/src/with-fiximports/g.go: -------------------------------------------------------------------------------- 1 | package a 2 | 3 | import ( // want "fiximports: Fix imports" 4 | "fmt" 5 | ) 6 | 7 | func fmtg() { 8 | // fmt still used after removal, but new strconv 9 | fmt.Printf("Hello, World!", fmt.Sprintf("%d", 123)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 10 | } 11 | -------------------------------------------------------------------------------- /analyzer/testdata/src/with-fiximports/g.go.golden: -------------------------------------------------------------------------------- 1 | package a 2 | 3 | import ( // want "fiximports: Fix imports" 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | func fmtg() { 9 | // fmt still used after removal, but new strconv 10 | fmt.Printf("Hello, World!", strconv.Itoa(123)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 11 | } 12 | -------------------------------------------------------------------------------- /analyzer/testdata/src/with-fiximports/b.go.golden: -------------------------------------------------------------------------------- 1 | package a 2 | 3 | import ( 4 | "strings" 5 | ) 6 | 7 | func loopconcat2() { 8 | // already strings 9 | s := "" 10 | var sSb10 strings.Builder 11 | for i := 0; i < 10; i++ { 12 | sSb10.WriteString("toto") // want "concat-loop: string concatenation in a loop" 13 | } 14 | s += sSb10.String() 15 | println("Hello, World!", strings.Fields(s)) 16 | } 17 | -------------------------------------------------------------------------------- /analyzer/testdata/src/with-fiximports/a.go.golden: -------------------------------------------------------------------------------- 1 | package a 2 | 3 | import ( 4 | "strings" 5 | ) 6 | 7 | func loopconcat() { // want "fiximports: Fix imports" 8 | // no imports, adding strings 9 | s := "" 10 | var sSb6 strings.Builder 11 | for i := 0; i < 10; i++ { 12 | sSb6.WriteString("toto") // want "concat-loop: string concatenation in a loop" 13 | } 14 | s += sSb6.String() 15 | println("Hello, World!", s) 16 | } 17 | -------------------------------------------------------------------------------- /analyzer/testdata/src/with-fiximports/c.go: -------------------------------------------------------------------------------- 1 | package a 2 | 3 | import ( 4 | "fmt" // want "fiximports: Fix imports" 5 | ) 6 | 7 | func loopconcat3() { 8 | // only fmt removed, but strings added 9 | s := "" 10 | for i := 0; i < 10; i++ { 11 | s += "toto" // want "concat-loop: string concatenation in a loop" 12 | } 13 | println("Hello, World!", fmt.Sprintf("%s", s)) // want "string-format: fmt.Sprintf can be replaced with just using the string" 14 | } 15 | -------------------------------------------------------------------------------- /analyzer/testdata/src/with-fiximports/d.go: -------------------------------------------------------------------------------- 1 | package a 2 | 3 | import ( 4 | "fmt" // want "fiximports: Fix imports" 5 | "strings" 6 | ) 7 | 8 | func loopconcat4() { 9 | // only fmt removed 10 | s := "" 11 | for i := 0; i < 10; i++ { 12 | s += "toto" // want "concat-loop: string concatenation in a loop" 13 | } 14 | println("Hello, World!", strings.Fields(fmt.Sprintf("%s", s))) // want "string-format: fmt.Sprintf can be replaced with just using the string" 15 | } 16 | -------------------------------------------------------------------------------- /.golangci.yaml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | run: 3 | allow-parallel-runners: true 4 | linters: 5 | enable: 6 | - errcheck 7 | - gosec 8 | - govet 9 | - ineffassign 10 | - staticcheck 11 | - unused 12 | - perfsprint 13 | exclusions: 14 | rules: 15 | - linters: 16 | - staticcheck 17 | - perfsprint 18 | path: '(.+)_test\.go' 19 | settings: 20 | staticcheck: 21 | checks: 22 | - "all" 23 | formatters: 24 | enable: 25 | - gofmt -------------------------------------------------------------------------------- /analyzer/testdata/src/with-fiximports/d.go.golden: -------------------------------------------------------------------------------- 1 | package a 2 | 3 | import ( 4 | // want "fiximports: Fix imports" 5 | "strings" 6 | ) 7 | 8 | func loopconcat4() { 9 | // only fmt removed 10 | s := "" 11 | var sSb11 strings.Builder 12 | for i := 0; i < 10; i++ { 13 | sSb11.WriteString("toto") // want "concat-loop: string concatenation in a loop" 14 | } 15 | s += sSb11.String() 16 | println("Hello, World!", strings.Fields(s)) // want "string-format: fmt.Sprintf can be replaced with just using the string" 17 | } 18 | -------------------------------------------------------------------------------- /analyzer/testdata/src/with-fiximports/c.go.golden: -------------------------------------------------------------------------------- 1 | package a 2 | 3 | import ( 4 | "strings" 5 | // want "fiximports: Fix imports" 6 | ) 7 | 8 | func loopconcat3() { 9 | // only fmt removed, but strings added 10 | s := "" 11 | var sSb10 strings.Builder 12 | for i := 0; i < 10; i++ { 13 | sSb10.WriteString("toto") // want "concat-loop: string concatenation in a loop" 14 | } 15 | s += sSb10.String() 16 | println("Hello, World!", s) // want "string-format: fmt.Sprintf can be replaced with just using the string" 17 | } 18 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: fmt tidy lint test bench install 2 | 3 | default: fmt tidy lint test install 4 | 5 | fmt: 6 | go fmt ./... 7 | 8 | tidy: 9 | go mod tidy 10 | 11 | lint: 12 | golangci-lint run --fix -v -c .golangci.yaml ./... 13 | 14 | test: 15 | go test -race ./... 16 | 17 | bench: 18 | # each benchmark runs for 5 seconds, in a single CPU (to make results more consistent); report memory allocation 19 | go test -bench=Bench ./... -benchtime 5s -cpu 1 -benchmem 20 | 21 | install: 22 | go install . 23 | perfsprint -h 2>&1 | head -n1 24 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 2 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 3 | golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= 4 | golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= 5 | golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= 6 | golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= 7 | golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= 8 | golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= 9 | -------------------------------------------------------------------------------- /analyzer/diagnostic.go: -------------------------------------------------------------------------------- 1 | package analyzer 2 | 3 | import ( 4 | "golang.org/x/tools/go/analysis" 5 | ) 6 | 7 | func newAnalysisDiagnostic( 8 | checker string, 9 | analysisRange analysis.Range, 10 | message string, 11 | suggestedFixes []analysis.SuggestedFix, 12 | ) *analysis.Diagnostic { 13 | if checker != "" { 14 | message = checker + ": " + message 15 | } 16 | 17 | return &analysis.Diagnostic{ 18 | Pos: analysisRange.Pos(), 19 | End: analysisRange.End(), 20 | SuggestedFixes: suggestedFixes, 21 | Message: message, 22 | Category: checker, // Possible hashtag available on the documentation 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | main: 11 | runs-on: ubuntu-latest 12 | strategy: 13 | matrix: 14 | go: ['stable', 'oldstable'] 15 | env: 16 | GOLANGCI_LINT_VERSION: v2.5.0 17 | steps: 18 | - name: Checkout code 19 | uses: actions/checkout@v5 20 | 21 | - name: Set up Go 22 | uses: actions/setup-go@v6 23 | with: 24 | go-version: ${{ matrix.go }} 25 | check-latest: true 26 | 27 | - name: Check and get dependencies 28 | run: | 29 | go mod tidy 30 | git diff --exit-code go.mod 31 | git diff --exit-code go.sum 32 | 33 | - name: Run golangci-lint ${{ env.GOLANGCI_LINT_VERSION }} 34 | uses: golangci/golangci-lint-action@v8 35 | with: 36 | args: --verbose 37 | version: ${{ env.GOLANGCI_LINT_VERSION }} 38 | 39 | - run: make test 40 | 41 | - run: make install 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Catena cyber 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /analyzer/testdata/src/with-concat-loop/p.go: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | import ( // want "fiximports: Fix imports" 4 | "fmt" 5 | ) 6 | 7 | func positive() { 8 | var s string 9 | words := []string{"one", "two", "three"} 10 | for w := range words { 11 | s += words[w] // want "concat-loop: string concatenation in a loop" 12 | } 13 | for w := range words { 14 | s = s + words[w] // want "concat-loop: string concatenation in a loop" 15 | } 16 | for w := 0; w < 10; w++ { 17 | s = s + "y" // want "concat-loop: string concatenation in a loop" 18 | } 19 | for w := 0; w < 10; w++ { 20 | if w%2 == 1 { 21 | s = s + "y" // want "concat-loop: string concatenation in a loop" 22 | } 23 | } 24 | nb := 0 25 | for w := 0; w < 10; w++ { 26 | if w%2 == 1 { 27 | nb += 1 28 | } else { 29 | s = s + "y" // want "concat-loop: string concatenation in a loop" 30 | } 31 | } 32 | for w := 0; w < 10; w++ { 33 | if w%2 == 1 { 34 | s = s + "x" // want "concat-loop: string concatenation in a loop" 35 | } else { 36 | s = s + "y" 37 | } 38 | } 39 | s2 := "prefix" 40 | for w := 0; w < 10; w++ { 41 | if w%2 == 1 { 42 | s2 = s2 + "x" 43 | } else { 44 | s = s + "y" // want "concat-loop: string concatenation in a loop" 45 | } 46 | } 47 | for w := 0; w < 10; w++ { 48 | s = s + "y" // want "concat-loop: string concatenation in a loop" 49 | if len(s)%3 == 1 { 50 | s = s + "," 51 | } 52 | } 53 | 54 | for w := 0; w < 10; w++ { 55 | s = fmt.Sprintf("%s+%s", s, "y") 56 | if w%2 == 1 { 57 | s = s + "," // want "concat-loop: string concatenation in a loop" 58 | } 59 | } 60 | 61 | for w := 0; w < 10; w++ { 62 | for y := 0; y < 10; y++ { 63 | s = s + "a" 64 | } 65 | s = s + "," // want "concat-loop: string concatenation in a loop" 66 | } 67 | 68 | for w := 0; w < 10; w++ { 69 | switch w { 70 | case 1: 71 | // do something 72 | default: 73 | s = s + "y" // want "concat-loop: string concatenation in a loop" 74 | } 75 | } 76 | } 77 | 78 | func negative() { 79 | for w := 0; w < 10; w++ { 80 | s := "local" 81 | s = s + "y" 82 | } 83 | for w := 0; w < 10; w++ { 84 | var s string 85 | s = s + "y" 86 | } 87 | for w := 0; w < 10; w++ { 88 | var s2, s string 89 | s = s + "y" 90 | _ = s 91 | _ = s2 92 | } 93 | for w := 0; w < 10; w++ { 94 | s2, s := "local", "same" 95 | s = s + "y" 96 | _ = s 97 | _ = s2 98 | } 99 | nb := 0 100 | for w := 0; w < 10; w++ { 101 | nb += w 102 | } 103 | for w := 0; w < 10; w++ { 104 | nb = nb + w 105 | } 106 | words := []string{"one", "two", "three"} 107 | var s string 108 | for w := range words { 109 | s = "toto" + words[w] 110 | } 111 | var s2 string 112 | for w := range words { 113 | s = s2 + words[w] 114 | } 115 | _ = s 116 | _ = s2 117 | } 118 | -------------------------------------------------------------------------------- /analyzer/testdata/src/with-concat-loop/p.go.golden: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | import ( // want "fiximports: Fix imports" 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | func positive() { 9 | var s string 10 | words := []string{"one", "two", "three"} 11 | var sSb10 strings.Builder 12 | for w := range words { 13 | sSb10.WriteString(words[w]) // want "concat-loop: string concatenation in a loop" 14 | } 15 | s += sSb10.String() 16 | var sSb13 strings.Builder 17 | for w := range words { 18 | sSb13.WriteString(words[w]) // want "concat-loop: string concatenation in a loop" 19 | } 20 | s += sSb13.String() 21 | var sSb16 strings.Builder 22 | for w := 0; w < 10; w++ { 23 | sSb16.WriteString("y") // want "concat-loop: string concatenation in a loop" 24 | } 25 | s += sSb16.String() 26 | var sSb19 strings.Builder 27 | for w := 0; w < 10; w++ { 28 | if w%2 == 1 { 29 | sSb19.WriteString("y") // want "concat-loop: string concatenation in a loop" 30 | } 31 | } 32 | s += sSb19.String() 33 | nb := 0 34 | var sSb25 strings.Builder 35 | for w := 0; w < 10; w++ { 36 | if w%2 == 1 { 37 | nb += 1 38 | } else { 39 | sSb25.WriteString("y") // want "concat-loop: string concatenation in a loop" 40 | } 41 | } 42 | s += sSb25.String() 43 | var sSb32 strings.Builder 44 | for w := 0; w < 10; w++ { 45 | if w%2 == 1 { 46 | sSb32.WriteString("x") // want "concat-loop: string concatenation in a loop" 47 | } else { 48 | sSb32.WriteString("y") 49 | } 50 | } 51 | s += sSb32.String() 52 | s2 := "prefix" 53 | var sSb40 strings.Builder 54 | var s2Sb40 strings.Builder 55 | for w := 0; w < 10; w++ { 56 | if w%2 == 1 { 57 | s2Sb40.WriteString("x") 58 | } else { 59 | sSb40.WriteString("y") // want "concat-loop: string concatenation in a loop" 60 | } 61 | } 62 | s += sSb40.String() 63 | s2 += s2Sb40.String() 64 | // FIXME check usages of string identifier s (and mayber others) in loop 65 | var sSb47 strings.Builder 66 | for w := 0; w < 10; w++ { 67 | sSb47.WriteString("y") // want "concat-loop: string concatenation in a loop" 68 | if len(s)%3 == 1 { 69 | sSb47.WriteString(",") 70 | } 71 | } 72 | s += sSb47.String() 73 | 74 | // FIXME check usages of string identifier s (and mayber others) in loop 75 | var sSb54 strings.Builder 76 | for w := 0; w < 10; w++ { 77 | s = fmt.Sprintf("%s+%s", s, "y") 78 | if w%2 == 1 { 79 | sSb54.WriteString(",") // want "concat-loop: string concatenation in a loop" 80 | } 81 | } 82 | s += sSb54.String() 83 | 84 | var sSb61 strings.Builder 85 | for w := 0; w < 10; w++ { 86 | for y := 0; y < 10; y++ { 87 | sSb61.WriteString("a") 88 | } 89 | sSb61.WriteString(",") // want "concat-loop: string concatenation in a loop" 90 | } 91 | s += sSb61.String() 92 | 93 | var sSb68 strings.Builder 94 | for w := 0; w < 10; w++ { 95 | switch w { 96 | case 1: 97 | // do something 98 | default: 99 | sSb68.WriteString("y") // want "concat-loop: string concatenation in a loop" 100 | } 101 | } 102 | s += sSb68.String() 103 | } 104 | 105 | func negative() { 106 | for w := 0; w < 10; w++ { 107 | s := "local" 108 | s = s + "y" 109 | } 110 | for w := 0; w < 10; w++ { 111 | var s string 112 | s = s + "y" 113 | } 114 | for w := 0; w < 10; w++ { 115 | var s2, s string 116 | s = s + "y" 117 | _ = s 118 | _ = s2 119 | } 120 | for w := 0; w < 10; w++ { 121 | s2, s := "local", "same" 122 | s = s + "y" 123 | _ = s 124 | _ = s2 125 | } 126 | nb := 0 127 | for w := 0; w < 10; w++ { 128 | nb += w 129 | } 130 | for w := 0; w < 10; w++ { 131 | nb = nb + w 132 | } 133 | words := []string{"one", "two", "three"} 134 | var s string 135 | for w := range words { 136 | s = "toto" + words[w] 137 | } 138 | var s2 string 139 | for w := range words { 140 | s = s2 + words[w] 141 | } 142 | _ = s 143 | _ = s2 144 | } 145 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # perfsprint 2 | 3 | [![CI](https://github.com/catenacyber/perfsprint/actions/workflows/ci.yml/badge.svg)](https://github.com/catenacyber/perfsprint/actions/workflows/ci.yml) 4 | [![Go Report Card](https://goreportcard.com/badge/github.com/catenacyber/perfsprint)](https://goreportcard.com/report/github.com/catenacyber/perfsprint?dummy=unused) 5 | 6 | Golang linter for performance that replaces uses of `fmt.Sprintf` and `fmt.Errorf` with better (both in CPU and memory) alternatives. 7 | 8 | ## Installation 9 | 10 | If you use `golangci-lint`, you can add it to your `.golangci.yml`: 11 | 12 | ```yaml 13 | version: "2" 14 | linters: 15 | enable: 16 | - perfsprint 17 | ``` 18 | 19 | ## Options 20 | 21 | The 6 options below cover all optimizations proposed by the linter. 22 | 23 | Some have suboptions for specific cases, including cases where the linter proposes a behavior change. 24 | 25 | - integer-format (formatting integer with the package `strconv`) 26 | - int-conversion : disable when the optimization adds a int/uint cast (readability) 27 | - error-format (formatting errors) 28 | - errorf : turns `fmt.Errorf` into `errors.New`, known behavior change, avoiding panic 29 | - err-error : turns `fmt.Sprintf(err)` and like into `err.Error()`, known behavior change, panicking for nil errors 30 | - string-format (formatting strings) 31 | - sprintf1 : turns `fmt.Sprintf(msg)` and like into `msg`, known behavior change, avoiding panic 32 | - strconcat : disable turning some `fmt.Sprintf` to a string concatenation (readability) 33 | - bool-format (formatting bool with `strconv.FormatBool`) 34 | - hex-format (formatting bytes with `hex.EncodeToString`) 35 | - concat-loop (replacing string concatenation in a loop by `strings.Builder`) 36 | - loop-other-ops : matches also if the loop has other operations than concatenation on the string 37 | 38 | There is also a `fix-imports` option that should auto-fix the imports section. 39 | It will add a comment `//TODO FIXME` if a package with the same name is already used. 40 | 41 | The `errorf` optimization is not always equivalent: 42 | ``` 43 | msg := "format string attack %s" 44 | // fmt.Errorf(msg) // original, panics 45 | errors.New(msg) // optimized, does not panic 46 | ``` 47 | 48 | The `sprintf1` optimization is not always equivalent: 49 | ``` 50 | msg := "format string attack %s" 51 | // a := fmt.Sprintf(msg) // original, panics 52 | a := msg // optimized, does not panic 53 | ``` 54 | 55 | The `err-error` optimization is not always equivalent: 56 | ``` 57 | var err error 58 | // fmt.Sprintf(err) // original, does not panic, prints 59 | err.Error() // optimized, panics ! 60 | ``` 61 | This optimization only works when the error is not nil, otherwise the resulting code will panic. 62 | 63 | The `loop-other-ops` optimization is not always equivalent. 64 | The proposed fix will likely fail to compile. 65 | Here is an example where the linter will rightly trigger but fail to propose a good fix. 66 | ``` 67 | s := "" 68 | for i:=0; i<10; i++ { 69 | s += "ab" 70 | if len(s) > 10 { // not a concatenation, no autofix 71 | return s // not a concatenation, no autofix 72 | } 73 | } 74 | ``` 75 | 76 | ## Replacements 77 | 78 | In general, using `fmt.Sprintf` is slow because it has to parse the arguments and format them according to various supported verbs (`%x`, `%d`, `%v`, etc.). 79 | 80 | This linter proposes the following replacements that are faster and allocate less memory. 81 | 82 | ``` 83 | fmt.Sprintf("%s", strVal) -> strVal 84 | fmt.Sprintf("%t", boolVal) -> strconv.FormatBool(boolBal) 85 | fmt.Sprintf("%x", hash) -> hex.EncodeToString(hash) 86 | fmt.Sprintf("%d", id) -> strconv.Itoa(id) 87 | fmt.Sprintf("%v", version) -> strconv.FormatUint(uint64(version), 10) 88 | ``` 89 | 90 | To know how fast each replacement is, run `make bench`. You will see something like this for each replacement: 91 | 92 | ``` 93 | cpu: Apple M4 Max 94 | BenchmarkStringFormatting/fmt.Sprint 227844582 25.39 ns/op 5 B/op 1 allocs/op 95 | BenchmarkStringFormatting/fmt.Sprintf 222438842 27.40 ns/op 5 B/op 1 allocs/op 96 | BenchmarkStringFormatting/REPLACEMENT:just_string 1000000000 0.2421 ns/op 0 B/op 0 allocs/op 97 | ``` 98 | 99 | The replacement is 100x faster (25 ns per operation vs 0.23 nanoseconds per operation) and allocates no memory (5 Bytes per operation vs 0 Bytes per operation). 100 | 101 | More in [tests](./analyzer/testdata/src) and in this blog: https://philpearl.github.io/post/bad_go_sprintf/ 102 | -------------------------------------------------------------------------------- /analyzer/analyzer_test.go: -------------------------------------------------------------------------------- 1 | package analyzer_test 2 | 3 | import ( 4 | "encoding/hex" 5 | "flag" 6 | "fmt" 7 | "io" 8 | "strconv" 9 | "testing" 10 | 11 | "github.com/catenacyber/perfsprint/analyzer" 12 | "golang.org/x/tools/go/analysis/analysistest" 13 | ) 14 | 15 | func TestAnalyzer(t *testing.T) { 16 | t.Parallel() 17 | 18 | t.Run("default", func(t *testing.T) { 19 | a := analyzer.New() 20 | analysistest.RunWithSuggestedFixes(t, analysistest.TestData(), a, "default") 21 | }) 22 | 23 | defaultAnalyzer := analyzer.New() 24 | defaultAnalyzer.Flags.VisitAll(func(f *flag.Flag) { 25 | if f.Name == "loop-other-ops" { 26 | return 27 | } 28 | name := f.Name 29 | var changedVal string 30 | switch f.DefValue { 31 | case "false": 32 | changedVal = "true" 33 | name = "with-" + f.Name 34 | case "true": 35 | changedVal = "false" 36 | name = "without-" + f.Name 37 | default: 38 | t.Fatalf("default value neither false or true") 39 | } 40 | 41 | t.Run(name, func(t *testing.T) { 42 | a := analyzer.New() 43 | if f.Name == "fiximports" { 44 | name = "with-fiximports" 45 | } else if f.Name == "concat-loop" { 46 | name = "with-concat-loop" 47 | err := a.Flags.Set("loop-other-ops", "true") 48 | if err != nil { 49 | t.Fatalf("failed to set %q flag", f.Name) 50 | } 51 | } else { 52 | err := a.Flags.Set(f.Name, changedVal) 53 | if err != nil { 54 | t.Fatalf("failed to set %q flag", f.Name) 55 | } 56 | } 57 | analysistest.RunWithSuggestedFixes(t, analysistest.TestData(), a, name) 58 | }) 59 | }) 60 | } 61 | 62 | func TestReplacements(t *testing.T) { 63 | t.Parallel() 64 | 65 | cases := []struct { 66 | before, after string 67 | }{ 68 | {before: fmt.Sprintf("%s", "hello"), after: "hello"}, //nolint:gosimple //https://staticcheck.io/docs/checks#S1025 69 | {before: fmt.Sprintf("%v", "hello"), after: "hello"}, 70 | {before: fmt.Sprint("hello"), after: "hello"}, //nolint:gosimple //https://staticcheck.io/docs/checks#S1039 71 | 72 | {before: fmt.Sprintf("%s", io.EOF), after: io.EOF.Error()}, 73 | {before: fmt.Sprintf("%v", io.EOF), after: io.EOF.Error()}, 74 | 75 | {before: fmt.Sprintf("%t", true), after: strconv.FormatBool(true)}, 76 | {before: fmt.Sprintf("%v", true), after: strconv.FormatBool(true)}, 77 | {before: fmt.Sprint(true), after: strconv.FormatBool(true)}, 78 | {before: fmt.Sprintf("%t", false), after: strconv.FormatBool(false)}, 79 | {before: fmt.Sprintf("%v", false), after: strconv.FormatBool(false)}, 80 | {before: fmt.Sprint(false), after: strconv.FormatBool(false)}, 81 | 82 | {before: fmt.Sprintf("%x", []byte{'a', 'b', 'c'}), after: hex.EncodeToString([]byte{'a', 'b', 'c'})}, 83 | 84 | {before: fmt.Sprintf("%d", 42), after: strconv.Itoa(42)}, 85 | {before: fmt.Sprintf("%v", 42), after: strconv.Itoa(42)}, 86 | {before: fmt.Sprint(42), after: strconv.Itoa(42)}, 87 | {before: fmt.Sprintf("%d", int8(42)), after: strconv.Itoa(int(int8(42)))}, 88 | {before: fmt.Sprintf("%v", int8(42)), after: strconv.Itoa(int(int8(42)))}, 89 | {before: fmt.Sprint(int8(42)), after: strconv.Itoa(int(int8(42)))}, 90 | {before: fmt.Sprintf("%d", int16(42)), after: strconv.Itoa(int(int16(42)))}, 91 | {before: fmt.Sprintf("%v", int16(42)), after: strconv.Itoa(int(int16(42)))}, 92 | {before: fmt.Sprint(int16(42)), after: strconv.Itoa(int(int16(42)))}, 93 | {before: fmt.Sprintf("%d", int32(42)), after: strconv.Itoa(int(int32(42)))}, 94 | {before: fmt.Sprintf("%v", int32(42)), after: strconv.Itoa(int(int32(42)))}, 95 | {before: fmt.Sprint(int32(42)), after: strconv.Itoa(int(int32(42)))}, 96 | {before: fmt.Sprintf("%d", int64(42)), after: strconv.FormatInt(int64(42), 10)}, 97 | {before: fmt.Sprintf("%v", int64(42)), after: strconv.FormatInt(int64(42), 10)}, 98 | {before: fmt.Sprint(int64(42)), after: strconv.FormatInt(int64(42), 10)}, 99 | 100 | {before: fmt.Sprintf("%d", uint(42)), after: strconv.FormatUint(uint64(uint(42)), 10)}, 101 | {before: fmt.Sprintf("%v", uint(42)), after: strconv.FormatUint(uint64(uint(42)), 10)}, 102 | {before: fmt.Sprint(uint(42)), after: strconv.FormatUint(uint64(uint(42)), 10)}, 103 | {before: fmt.Sprintf("%d", uint8(42)), after: strconv.FormatUint(uint64(uint8(42)), 10)}, 104 | {before: fmt.Sprintf("%v", uint8(42)), after: strconv.FormatUint(uint64(uint8(42)), 10)}, 105 | {before: fmt.Sprint(uint8(42)), after: strconv.FormatUint(uint64(uint8(42)), 10)}, 106 | {before: fmt.Sprintf("%d", uint16(42)), after: strconv.FormatUint(uint64(uint16(42)), 10)}, 107 | {before: fmt.Sprintf("%v", uint16(42)), after: strconv.FormatUint(uint64(uint16(42)), 10)}, 108 | {before: fmt.Sprint(uint16(42)), after: strconv.FormatUint(uint64(uint16(42)), 10)}, 109 | {before: fmt.Sprintf("%d", uint32(42)), after: strconv.FormatUint(uint64(uint32(42)), 10)}, 110 | {before: fmt.Sprintf("%v", uint32(42)), after: strconv.FormatUint(uint64(uint32(42)), 10)}, 111 | {before: fmt.Sprint(uint32(42)), after: strconv.FormatUint(uint64(uint32(42)), 10)}, 112 | {before: fmt.Sprintf("%d", uint64(42)), after: strconv.FormatUint(uint64(42), 10)}, 113 | {before: fmt.Sprint(uint64(42)), after: strconv.FormatUint(uint64(42), 10)}, 114 | {before: fmt.Sprintf("%v", uint64(42)), after: strconv.FormatUint(uint64(42), 10)}, 115 | } 116 | for _, tt := range cases { 117 | t.Run("", func(t *testing.T) { 118 | if tt.before != tt.after { 119 | t.Fatalf("%s != %s", tt.before, tt.after) 120 | } 121 | }) 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /analyzer/replacements_bench_test.go: -------------------------------------------------------------------------------- 1 | package analyzer_test 2 | 3 | import ( 4 | "context" 5 | "encoding/hex" 6 | "errors" 7 | "fmt" 8 | "math" 9 | "strconv" 10 | "strings" 11 | "testing" 12 | ) 13 | 14 | func BenchmarkStringFormatting(b *testing.B) { 15 | b.Run("fmt.Sprint", func(b *testing.B) { 16 | for n := 0; n < b.N; n++ { 17 | _ = fmt.Sprint("hello") //nolint:gosimple //https://staticcheck.io/docs/checks#S1039 18 | } 19 | }) 20 | 21 | b.Run("fmt.Sprintf", func(b *testing.B) { 22 | for n := 0; n < b.N; n++ { 23 | _ = fmt.Sprintf("%s", "hello") //nolint:gosimple //https://staticcheck.io/docs/checks#S1025 24 | } 25 | }) 26 | 27 | b.Run("REPLACEMENT:just string", func(b *testing.B) { 28 | for n := 0; n < b.N; n++ { 29 | _ = "hello" 30 | } 31 | }) 32 | } 33 | 34 | func BenchmarkErrorFormatting(b *testing.B) { 35 | b.Run("fmt.Sprint", func(b *testing.B) { 36 | for n := 0; n < b.N; n++ { 37 | _ = fmt.Sprint(context.DeadlineExceeded) 38 | } 39 | }) 40 | 41 | b.Run("fmt.Sprintf", func(b *testing.B) { 42 | for n := 0; n < b.N; n++ { 43 | _ = fmt.Sprintf("%s", context.DeadlineExceeded) 44 | } 45 | }) 46 | 47 | b.Run("REPLACEMENT:Error()", func(b *testing.B) { 48 | for n := 0; n < b.N; n++ { 49 | _ = context.DeadlineExceeded.Error() 50 | } 51 | }) 52 | } 53 | 54 | func BenchmarkFormattingError(b *testing.B) { 55 | b.Run("fmt.Errorf", func(b *testing.B) { 56 | for n := 0; n < b.N; n++ { 57 | _ = fmt.Errorf("onlystring") 58 | } 59 | }) 60 | 61 | b.Run("REPLACEMENT:errors.New", func(b *testing.B) { 62 | for n := 0; n < b.N; n++ { 63 | _ = errors.New("onlystring") 64 | } 65 | }) 66 | } 67 | 68 | func BenchmarkBoolFormatting(b *testing.B) { 69 | b.Run("fmt.Sprint", func(b *testing.B) { 70 | for n := 0; n < b.N; n++ { 71 | _ = fmt.Sprint(true) 72 | } 73 | }) 74 | 75 | b.Run("fmt.Sprintf", func(b *testing.B) { 76 | for n := 0; n < b.N; n++ { 77 | _ = fmt.Sprintf("%t", true) 78 | } 79 | }) 80 | 81 | b.Run("REPLACEMENT:strconv.FormatBool", func(b *testing.B) { 82 | for n := 0; n < b.N; n++ { 83 | _ = strconv.FormatBool(true) 84 | } 85 | }) 86 | } 87 | 88 | func BenchmarkHexEncoding(b *testing.B) { 89 | b.Run("fmt.Sprintf", func(b *testing.B) { 90 | for n := 0; n < b.N; n++ { 91 | _ = fmt.Sprintf("%x", []byte{'a', 'b', 'c'}) 92 | } 93 | }) 94 | 95 | b.Run("REPLACEMENT:hex.EncodeToString", func(b *testing.B) { 96 | for n := 0; n < b.N; n++ { 97 | _ = hex.EncodeToString([]byte{'a', 'b', 'c'}) 98 | } 99 | }) 100 | } 101 | 102 | func BenchmarkHexArrayEncoding(b *testing.B) { 103 | b.Run("fmt.Sprintf", func(b *testing.B) { 104 | for n := 0; n < b.N; n++ { 105 | val := [3]byte{'a', 'b', 'c'} 106 | _ = fmt.Sprintf("%x", val) 107 | } 108 | }) 109 | 110 | b.Run("REPLACEMENT:hex.EncodeToString", func(b *testing.B) { 111 | for n := 0; n < b.N; n++ { 112 | val := [3]byte{'a', 'b', 'c'} 113 | _ = hex.EncodeToString(val[:]) 114 | } 115 | }) 116 | } 117 | 118 | func BenchmarkIntFormatting(b *testing.B) { 119 | b.Run("fmt.Sprint", func(b *testing.B) { 120 | for n := 0; n < b.N; n++ { 121 | _ = fmt.Sprint(math.MaxInt) 122 | } 123 | }) 124 | 125 | b.Run("fmt.Sprintf", func(b *testing.B) { 126 | for n := 0; n < b.N; n++ { 127 | _ = fmt.Sprintf("%d", math.MaxInt) 128 | } 129 | }) 130 | 131 | b.Run("REPLACEMENT:strconv.Itoa", func(b *testing.B) { 132 | for n := 0; n < b.N; n++ { 133 | _ = strconv.Itoa(math.MaxInt) 134 | } 135 | }) 136 | } 137 | 138 | func BenchmarkIntConversionFormatting(b *testing.B) { 139 | b.Run("fmt.Sprint", func(b *testing.B) { 140 | u := int32(0x12345678) 141 | for n := 0; n < b.N; n++ { 142 | _ = fmt.Sprint(u) 143 | } 144 | }) 145 | 146 | b.Run("fmt.Sprintf", func(b *testing.B) { 147 | u := int32(0x12345678) 148 | for n := 0; n < b.N; n++ { 149 | _ = fmt.Sprintf("%d", u) 150 | } 151 | }) 152 | 153 | b.Run("REPLACEMENT:strconv.FormatInt", func(b *testing.B) { 154 | u := int32(0x12345678) 155 | for n := 0; n < b.N; n++ { 156 | _ = strconv.FormatInt(int64(u), 10) 157 | } 158 | }) 159 | } 160 | 161 | func BenchmarkUintFormatting(b *testing.B) { 162 | b.Run("fmt.Sprint", func(b *testing.B) { 163 | for n := 0; n < b.N; n++ { 164 | _ = fmt.Sprint(uint64(math.MaxUint)) 165 | } 166 | }) 167 | 168 | b.Run("fmt.Sprintf", func(b *testing.B) { 169 | for n := 0; n < b.N; n++ { 170 | _ = fmt.Sprintf("%d", uint64(math.MaxUint)) 171 | } 172 | }) 173 | 174 | b.Run("REPLACEMENT:strconv.FormatUint", func(b *testing.B) { 175 | for n := 0; n < b.N; n++ { 176 | _ = strconv.FormatUint(math.MaxUint, 10) 177 | } 178 | }) 179 | } 180 | 181 | func BenchmarkUintHexFormatting(b *testing.B) { 182 | b.Run("fmt.Sprintf", func(b *testing.B) { 183 | for n := 0; n < b.N; n++ { 184 | _ = fmt.Sprintf("%x", uint64(math.MaxUint)) 185 | } 186 | }) 187 | 188 | b.Run("REPLACEMENT:strconv.FormatUint", func(b *testing.B) { 189 | for n := 0; n < b.N; n++ { 190 | _ = strconv.FormatUint(math.MaxUint, 16) 191 | } 192 | }) 193 | } 194 | 195 | func BenchmarkStringAdditionFormatting(b *testing.B) { 196 | b.Run("fmt.Sprintf", func(b *testing.B) { 197 | for n := 0; n < b.N; n++ { 198 | _ = fmt.Sprintf("Hello %s", "world") 199 | } 200 | }) 201 | 202 | b.Run("REPLACEMENT:string concatenation", func(b *testing.B) { 203 | for n := 0; n < b.N; n++ { 204 | _ = "Hello " + "world" 205 | } 206 | }) 207 | } 208 | 209 | func BenchmarkStringConcatLoop(b *testing.B) { 210 | words := []string{"one", "two", "three", "four", "five", "six", "seven", "eight"} 211 | b.Run("fmt.Sprintf", func(b *testing.B) { 212 | for n := 0; n < b.N; n++ { 213 | s := "" 214 | for w := range words { 215 | s += words[w] 216 | } 217 | _ = s 218 | } 219 | }) 220 | 221 | b.Run("strings Builder", func(b *testing.B) { 222 | for n := 0; n < b.N; n++ { 223 | var s string 224 | var sb strings.Builder 225 | for w := range words { 226 | sb.WriteString(words[w]) 227 | } 228 | s = sb.String() 229 | _ = s 230 | } 231 | }) 232 | } 233 | 234 | func BenchmarkStringConcatLoopBig(b *testing.B) { 235 | words := make([]string, 0x10000) 236 | for i := 0; i < 0x10000; i++ { 237 | words[i] = strconv.Itoa(i) 238 | } 239 | b.Run("fmt.Sprintf", func(b *testing.B) { 240 | for n := 0; n < b.N; n++ { 241 | s := "" 242 | for w := range words { 243 | s += words[w] 244 | } 245 | _ = s 246 | } 247 | }) 248 | 249 | b.Run("strings Builder", func(b *testing.B) { 250 | for n := 0; n < b.N; n++ { 251 | var s string 252 | var sb strings.Builder 253 | for w := range words { 254 | sb.WriteString(words[w]) 255 | } 256 | s = sb.String() 257 | _ = s 258 | } 259 | }) 260 | } 261 | -------------------------------------------------------------------------------- /analyzer/testdata/src/without-integer-format/p.go.golden: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | import ( // want "Fix imports" 4 | "encoding/hex" 5 | "errors" 6 | "fmt" 7 | "io" 8 | "log" 9 | "net/url" 10 | "os" 11 | "strconv" 12 | "time" 13 | ) 14 | 15 | var errSentinel = errors.New("connection refused") 16 | 17 | func positive() { 18 | var s string 19 | "hello" // want "string-format: fmt.Sprintf can be replaced with just using the string" 20 | "hello" // want "string-format: fmt.Sprintf can be replaced with just using the string" 21 | "hello" // want "string-format: fmt.Sprintf can be replaced with just using the string" 22 | "hello" // want "string-format: fmt.Sprint can be replaced with just using the string" 23 | s // want "string-format: fmt.Sprintf can be replaced with just using the string" 24 | s // want "string-format: fmt.Sprintf can be replaced with just using the string" 25 | s // want "string-format: fmt.Sprintf can be replaced with just using the string" 26 | s // want "string-format: fmt.Sprint can be replaced with just using the string" 27 | errors.New("hello") // want "error-format: fmt.Errorf can be replaced with errors.New" 28 | 29 | "Hello " + s // want "string-format: fmt.Sprintf can be replaced with string concatenation" 30 | s + " says Hello" // want "string-format: fmt.Sprintf can be replaced with string concatenation" 31 | "Hello says " + s // want "string-format: fmt.Sprintf can be replaced with string concatenation" 32 | 33 | var err error 34 | fmt.Sprintf("%s", errSentinel) 35 | fmt.Sprintf("%v", errSentinel) 36 | fmt.Sprint(errSentinel) 37 | fmt.Sprintf("%s", io.EOF) 38 | fmt.Sprintf("%v", io.EOF) 39 | fmt.Sprint(io.EOF) 40 | fmt.Sprintf("%s", err) 41 | fmt.Sprintf("%v", err) 42 | fmt.Sprint(err) 43 | 44 | var b bool 45 | strconv.FormatBool(true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 46 | strconv.FormatBool(true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 47 | strconv.FormatBool(true) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 48 | strconv.FormatBool(false) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 49 | strconv.FormatBool(false) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 50 | strconv.FormatBool(false) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 51 | strconv.FormatBool(b) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 52 | strconv.FormatBool(b) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 53 | strconv.FormatBool(b) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 54 | 55 | var bs []byte 56 | var ba [3]byte 57 | hex.EncodeToString([]byte{'a'}) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 58 | hex.EncodeToString([]uint8{'b'}) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 59 | hex.EncodeToString(bs) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 60 | hex.EncodeToString(ba[:]) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 61 | 62 | var i int 63 | var i8 int8 64 | var i16 int16 65 | var i32 int32 66 | var i64 int64 67 | fmt.Sprintf("%d", i) 68 | fmt.Sprintf("%v", i) 69 | fmt.Sprint(i) 70 | fmt.Sprintf("%d", 42) 71 | fmt.Sprintf("%v", 42) 72 | fmt.Sprint(42) 73 | fmt.Sprintf("%d", i8) 74 | fmt.Sprintf("%v", i8) 75 | fmt.Sprint(i8) 76 | fmt.Sprintf("%d", int8(42)) 77 | fmt.Sprintf("%v", int8(42)) 78 | fmt.Sprint(int8(42)) 79 | fmt.Sprintf("%d", i16) 80 | fmt.Sprintf("%v", i16) 81 | fmt.Sprint(i16) 82 | fmt.Sprintf("%d", int16(42)) 83 | fmt.Sprintf("%v", int16(42)) 84 | fmt.Sprint(int16(42)) 85 | fmt.Sprintf("%d", i32) 86 | fmt.Sprintf("%v", i32) 87 | fmt.Sprint(i32) 88 | fmt.Sprintf("%d", int32(42)) 89 | fmt.Sprintf("%v", int32(42)) 90 | fmt.Sprint(int32(42)) 91 | fmt.Sprintf("%d", i64) 92 | fmt.Sprintf("%v", i64) 93 | fmt.Sprint(i64) 94 | fmt.Sprintf("%d", int64(42)) 95 | fmt.Sprintf("%v", int64(42)) 96 | fmt.Sprint(int64(42)) 97 | 98 | var ui uint 99 | var ui8 uint8 100 | var ui16 uint16 101 | var ui32 uint32 102 | var ui64 uint64 103 | fmt.Sprintf("%d", ui) 104 | fmt.Sprintf("%v", ui) 105 | fmt.Sprint(ui) 106 | fmt.Sprintf("%d", uint(42)) 107 | fmt.Sprintf("%v", uint(42)) 108 | fmt.Sprint(uint(42)) 109 | fmt.Sprintf("%d", ui8) 110 | fmt.Sprintf("%v", ui8) 111 | fmt.Sprint(ui8) 112 | fmt.Sprintf("%d", uint8(42)) 113 | fmt.Sprintf("%v", uint8(42)) 114 | fmt.Sprint(uint8(42)) 115 | fmt.Sprintf("%d", ui16) 116 | fmt.Sprintf("%v", ui16) 117 | fmt.Sprint(ui16) 118 | fmt.Sprintf("%d", uint16(42)) 119 | fmt.Sprintf("%v", uint16(42)) 120 | fmt.Sprint(uint16(42)) 121 | fmt.Sprintf("%d", ui32) 122 | fmt.Sprintf("%v", ui32) 123 | fmt.Sprint(ui32) 124 | fmt.Sprintf("%d", uint32(42)) 125 | fmt.Sprintf("%v", uint32(42)) 126 | fmt.Sprint(uint32(42)) 127 | fmt.Sprintf("%d", ui64) 128 | fmt.Sprintf("%v", ui64) 129 | fmt.Sprintf("%x", ui64) 130 | fmt.Sprintf("%x", uint(42)) 131 | fmt.Sprint(ui64) 132 | fmt.Sprintf("%d", uint64(42)) 133 | fmt.Sprintf("%v", uint64(42)) 134 | fmt.Sprint(uint64(42)) 135 | } 136 | 137 | func suggestedFixesTest() { 138 | _ = func() string { 139 | if false { 140 | return "replace me" // want "string-format: fmt.Sprint can be replaced with just using the string" 141 | } 142 | return "replace me" // want "string-format: fmt.Sprintf can be replaced with just using the string" 143 | } 144 | 145 | fmt.Println(fmt.Sprint(errSentinel)) 146 | fmt.Println(fmt.Sprintf("%s", errSentinel)) 147 | 148 | _ = func() string { 149 | switch 42 { 150 | case 1: 151 | return strconv.FormatBool(false) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 152 | case 2: 153 | return strconv.FormatBool(true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 154 | } 155 | return "" 156 | } 157 | 158 | var offset int 159 | params := url.Values{} 160 | params.Set("offset", fmt.Sprintf("%d", offset)) 161 | params.Set("offset", fmt.Sprint(offset)) 162 | 163 | var pubKey []byte 164 | if verifyPubKey := true; verifyPubKey { 165 | log.Println("pubkey=" + hex.EncodeToString(pubKey)) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 166 | } 167 | 168 | var metaHash [16]byte 169 | fn := fmt.Sprintf("%s.%x", "coverage.MetaFilePref", metaHash) 170 | _ = "tmp." + fn + fmt.Sprintf("%d", time.Now().UnixNano()) 171 | _ = "tmp." + fn + fmt.Sprint(time.Now().UnixNano()) 172 | 173 | var change struct{ User struct{ ID uint } } 174 | var userStr string 175 | if id := change.User.ID; id != 0 { 176 | userStr = fmt.Sprintf("%d", id) 177 | userStr = fmt.Sprint(id) 178 | } 179 | _ = userStr 180 | } 181 | 182 | func negative() { 183 | const val = "val%d" 184 | 185 | _ = int32(42) 186 | 187 | fmt.Scan(42) 188 | fmt.Scanf("%d", 42) 189 | fmt.Println("%d", 42) 190 | fmt.Printf("%d") 191 | fmt.Printf("%v") 192 | fmt.Printf("%d", 42) 193 | fmt.Printf("%s %d", "hello", 42) 194 | fmt.Errorf("this is %s", "complex") 195 | 196 | fmt.Fprint(os.Stdout, "%d", 42) 197 | fmt.Fprintf(os.Stdout, "test") 198 | fmt.Fprintf(os.Stdout, "%d") 199 | fmt.Fprintf(os.Stdout, "%v") 200 | fmt.Fprintf(os.Stdout, "%d", 42) 201 | fmt.Fprintf(os.Stdout, "%s %d", "hello", 42) 202 | 203 | fmt.Sprint("test", 42) 204 | fmt.Sprint(42, 42) 205 | fmt.Sprintf("%d", 42, 42) 206 | fmt.Sprintf("%#d", 42) 207 | fmt.Sprintf("value %d", 42) 208 | fmt.Sprintf(val, 42) 209 | fmt.Sprintf("%s %v", "hello", "world") 210 | fmt.Sprintf("%#v", 42) 211 | fmt.Sprintf("%T", struct{ string }{}) 212 | fmt.Sprintf("%%v", 42) 213 | fmt.Sprintf("%3d", 42) 214 | fmt.Sprintf("% d", 42) 215 | fmt.Sprintf("%-10d", 42) 216 | fmt.Sprintf("%s %[1]s", "hello") 217 | fmt.Sprintf("%[1]s %[1]s", "hello") 218 | fmt.Sprintf("%[2]d %[1]d\n", 11, 22) 219 | fmt.Sprintf("%[3]*.[2]*[1]f", 12.0, 2, 6) 220 | fmt.Sprintf("%d %d %#[1]x %#x", 16, 17) 221 | 222 | // Integer. 223 | fmt.Sprintf("%#x", uint64(42)) 224 | fmt.Sprintf("%#v", uint64(42)) 225 | fmt.Sprintf("%#b", 42) 226 | fmt.Sprintf("%#o", 42) 227 | fmt.Sprintf("%#x", 42) 228 | fmt.Sprintf("%#X", 42) 229 | 230 | fmt.Sprintf("%b", 42) 231 | fmt.Sprintf("%c", 42) 232 | fmt.Sprintf("%o", 42) 233 | fmt.Sprintf("%O", 42) 234 | fmt.Sprintf("%q", 42) 235 | fmt.Sprintf("%x", 42) 236 | fmt.Sprintf("%X", 42) 237 | 238 | // Floating point. 239 | fmt.Sprintf("%9f", 42.42) 240 | fmt.Sprintf("%.2f", 42.42) 241 | fmt.Sprintf("%.2f", 42.42) 242 | fmt.Sprintf("%9.2f", 42.42) 243 | fmt.Sprintf("%9.f", 42.42) 244 | fmt.Sprintf("%.3g", 42.42) 245 | 246 | fmt.Sprintf("%b", float32(42.42)) 247 | fmt.Sprintf("%e", float32(42.42)) 248 | fmt.Sprintf("%E", float32(42.42)) 249 | fmt.Sprintf("%f", float32(42.42)) 250 | fmt.Sprintf("%F", float32(42.42)) 251 | fmt.Sprintf("%g", float32(42.42)) 252 | fmt.Sprintf("%G", float32(42.42)) 253 | fmt.Sprintf("%x", float32(42.42)) 254 | fmt.Sprintf("%X", float32(42.42)) 255 | fmt.Sprintf("%v", float32(42.42)) 256 | 257 | fmt.Sprintf("%b", 42.42) 258 | fmt.Sprintf("%e", 42.42) 259 | fmt.Sprintf("%E", 42.42) 260 | fmt.Sprintf("%f", 42.42) 261 | fmt.Sprintf("%F", 42.42) 262 | fmt.Sprintf("%g", 42.42) 263 | fmt.Sprintf("%G", 42.42) 264 | fmt.Sprintf("%x", 42.42) 265 | fmt.Sprintf("%X", 42.42) 266 | fmt.Sprintf("%v", 42.42) 267 | 268 | fmt.Sprintf("%b", 42i+42) 269 | fmt.Sprintf("%e", 42i+42) 270 | fmt.Sprintf("%E", 42i+42) 271 | fmt.Sprintf("%f", 42i+42) 272 | fmt.Sprintf("%F", 42i+42) 273 | fmt.Sprintf("%g", 42i+42) 274 | fmt.Sprintf("%G", 42i+42) 275 | fmt.Sprintf("%x", 42i+42) 276 | fmt.Sprintf("%X", 42i+42) 277 | fmt.Sprintf("%v", 42i+42) 278 | 279 | // String & slice of bytes. 280 | fmt.Sprintf("%q", "hello") 281 | fmt.Sprintf("%#q", `"hello"`) 282 | fmt.Sprintf("%+q", "hello") 283 | fmt.Sprintf("%X", "hello") 284 | 285 | // Slice. 286 | fmt.Sprintf("%x", []uint16{'d'}) 287 | fmt.Sprintf("%x", []uint32{'d'}) 288 | fmt.Sprintf("%x", []uint64{'d'}) 289 | fmt.Sprintf("%x", []uint{'d'}) 290 | fmt.Sprintf("%x", [1]byte{'c'}) 291 | fmt.Sprintf("%x", [1]uint8{'d'}) 292 | fmt.Sprintf("%x", [1]uint16{'d'}) 293 | fmt.Sprintf("%x", [1]uint32{'d'}) 294 | fmt.Sprintf("%x", [1]uint64{'d'}) 295 | fmt.Sprintf("%x", [1]uint{'d'}) 296 | fmt.Sprintf("%x", []int8{1}) 297 | fmt.Sprintf("%x", []int16{1}) 298 | fmt.Sprintf("%x", []int32{1}) 299 | fmt.Sprintf("%x", []int64{1}) 300 | fmt.Sprintf("%x", []int{1}) 301 | fmt.Sprintf("%x", [...]int8{1}) 302 | fmt.Sprintf("%x", [...]int16{1}) 303 | fmt.Sprintf("%x", [...]int32{1}) 304 | fmt.Sprintf("%x", [...]int64{1}) 305 | fmt.Sprintf("%x", [...]int{1}) 306 | fmt.Sprintf("%x", []string{"hello"}) 307 | fmt.Sprintf("%x", []rune{'a'}) 308 | 309 | fmt.Sprintf("% x", []byte{1, 2, 3}) 310 | fmt.Sprintf("% X", []byte{1, 2, 3}) 311 | fmt.Sprintf("%p", []byte{1, 2, 3}) 312 | fmt.Sprintf("%#p", []byte{1, 2, 3}) 313 | 314 | // Pointer. 315 | var ptr *int 316 | fmt.Sprintf("%v", ptr) 317 | fmt.Sprintf("%b", ptr) 318 | fmt.Sprintf("%d", ptr) 319 | fmt.Sprintf("%o", ptr) 320 | fmt.Sprintf("%x", ptr) 321 | fmt.Sprintf("%X", ptr) 322 | } 323 | 324 | func malformed() { 325 | fmt.Sprintf("%d", "example") 326 | fmt.Sprintf("%T", "example") 327 | fmt.Sprintf("%t", "example") 328 | fmt.Sprintf("%b", "example") 329 | fmt.Sprintf("%e", "example") 330 | fmt.Sprintf("%E", "example") 331 | fmt.Sprintf("%f", "example") 332 | fmt.Sprintf("%F", "example") 333 | fmt.Sprintf("%g", "example") 334 | fmt.Sprintf("%G", "example") 335 | fmt.Sprintf("%x", "example") 336 | fmt.Sprintf("%X", "example") 337 | 338 | fmt.Sprintf("%d", errSentinel) 339 | fmt.Sprintf("%T", errSentinel) 340 | fmt.Sprintf("%t", errSentinel) 341 | fmt.Sprintf("%b", errSentinel) 342 | fmt.Sprintf("%e", errSentinel) 343 | fmt.Sprintf("%E", errSentinel) 344 | fmt.Sprintf("%f", errSentinel) 345 | fmt.Sprintf("%F", errSentinel) 346 | fmt.Sprintf("%g", errSentinel) 347 | fmt.Sprintf("%G", errSentinel) 348 | fmt.Sprintf("%x", errSentinel) 349 | fmt.Sprintf("%X", errSentinel) 350 | 351 | fmt.Sprintf("%d", true) 352 | fmt.Sprintf("%T", true) 353 | fmt.Sprintf("%b", true) 354 | fmt.Sprintf("%e", true) 355 | fmt.Sprintf("%E", true) 356 | fmt.Sprintf("%f", true) 357 | fmt.Sprintf("%F", true) 358 | fmt.Sprintf("%g", true) 359 | fmt.Sprintf("%G", true) 360 | fmt.Sprintf("%x", true) 361 | fmt.Sprintf("%X", true) 362 | 363 | var bb []byte 364 | fmt.Sprintf("%d", bb) 365 | fmt.Sprintf("%T", bb) 366 | fmt.Sprintf("%t", bb) 367 | fmt.Sprintf("%b", bb) 368 | fmt.Sprintf("%e", bb) 369 | fmt.Sprintf("%E", bb) 370 | fmt.Sprintf("%f", bb) 371 | fmt.Sprintf("%F", bb) 372 | fmt.Sprintf("%g", bb) 373 | fmt.Sprintf("%G", bb) 374 | fmt.Sprintf("%X", bb) 375 | fmt.Sprintf("%v", bb) 376 | 377 | fmt.Sprintf("%T", 42) 378 | fmt.Sprintf("%t", 42) 379 | fmt.Sprintf("%b", 42) 380 | fmt.Sprintf("%e", 42) 381 | fmt.Sprintf("%E", 42) 382 | fmt.Sprintf("%f", 42) 383 | fmt.Sprintf("%F", 42) 384 | fmt.Sprintf("%g", 42) 385 | fmt.Sprintf("%G", 42) 386 | fmt.Sprintf("%x", 42) 387 | fmt.Sprintf("%X", 42) 388 | 389 | fmt.Sprintf("%T", uint(42)) 390 | fmt.Sprintf("%t", uint(42)) 391 | fmt.Sprintf("%b", uint(42)) 392 | fmt.Sprintf("%e", uint(42)) 393 | fmt.Sprintf("%E", uint(42)) 394 | fmt.Sprintf("%f", uint(42)) 395 | fmt.Sprintf("%F", uint(42)) 396 | fmt.Sprintf("%g", uint(42)) 397 | fmt.Sprintf("%G", uint(42)) 398 | fmt.Sprintf("%X", uint(42)) 399 | 400 | fmt.Sprintf("%d", 42.42) 401 | fmt.Sprintf("%d", map[string]string{}) 402 | fmt.Sprint(make(chan int)) 403 | fmt.Sprint([]int{1, 2, 3}) 404 | } 405 | -------------------------------------------------------------------------------- /analyzer/testdata/src/without-integer-format/p.go: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | import ( // want "Fix imports" 4 | "errors" 5 | "fmt" 6 | "io" 7 | "log" 8 | "net/url" 9 | "os" 10 | "time" 11 | ) 12 | 13 | var errSentinel = errors.New("connection refused") 14 | 15 | func positive() { 16 | var s string 17 | fmt.Sprintf("%s", "hello") // want "string-format: fmt.Sprintf can be replaced with just using the string" 18 | fmt.Sprintf("%v", "hello") // want "string-format: fmt.Sprintf can be replaced with just using the string" 19 | fmt.Sprintf("hello") // want "string-format: fmt.Sprintf can be replaced with just using the string" 20 | fmt.Sprint("hello") // want "string-format: fmt.Sprint can be replaced with just using the string" 21 | fmt.Sprintf("%s", s) // want "string-format: fmt.Sprintf can be replaced with just using the string" 22 | fmt.Sprintf("%[1]s", s) // want "string-format: fmt.Sprintf can be replaced with just using the string" 23 | fmt.Sprintf("%v", s) // want "string-format: fmt.Sprintf can be replaced with just using the string" 24 | fmt.Sprint(s) // want "string-format: fmt.Sprint can be replaced with just using the string" 25 | fmt.Errorf("hello") // want "error-format: fmt.Errorf can be replaced with errors.New" 26 | 27 | fmt.Sprintf("Hello %s", s) // want "string-format: fmt.Sprintf can be replaced with string concatenation" 28 | fmt.Sprintf("%s says Hello", s) // want "string-format: fmt.Sprintf can be replaced with string concatenation" 29 | fmt.Sprintf("Hello says %[1]s", s) // want "string-format: fmt.Sprintf can be replaced with string concatenation" 30 | 31 | var err error 32 | fmt.Sprintf("%s", errSentinel) 33 | fmt.Sprintf("%v", errSentinel) 34 | fmt.Sprint(errSentinel) 35 | fmt.Sprintf("%s", io.EOF) 36 | fmt.Sprintf("%v", io.EOF) 37 | fmt.Sprint(io.EOF) 38 | fmt.Sprintf("%s", err) 39 | fmt.Sprintf("%v", err) 40 | fmt.Sprint(err) 41 | 42 | var b bool 43 | fmt.Sprintf("%t", true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 44 | fmt.Sprintf("%v", true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 45 | fmt.Sprint(true) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 46 | fmt.Sprintf("%t", false) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 47 | fmt.Sprintf("%v", false) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 48 | fmt.Sprint(false) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 49 | fmt.Sprintf("%t", b) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 50 | fmt.Sprintf("%v", b) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 51 | fmt.Sprint(b) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 52 | 53 | var bs []byte 54 | var ba [3]byte 55 | fmt.Sprintf("%x", []byte{'a'}) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 56 | fmt.Sprintf("%x", []uint8{'b'}) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 57 | fmt.Sprintf("%x", bs) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 58 | fmt.Sprintf("%x", ba) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 59 | 60 | var i int 61 | var i8 int8 62 | var i16 int16 63 | var i32 int32 64 | var i64 int64 65 | fmt.Sprintf("%d", i) 66 | fmt.Sprintf("%v", i) 67 | fmt.Sprint(i) 68 | fmt.Sprintf("%d", 42) 69 | fmt.Sprintf("%v", 42) 70 | fmt.Sprint(42) 71 | fmt.Sprintf("%d", i8) 72 | fmt.Sprintf("%v", i8) 73 | fmt.Sprint(i8) 74 | fmt.Sprintf("%d", int8(42)) 75 | fmt.Sprintf("%v", int8(42)) 76 | fmt.Sprint(int8(42)) 77 | fmt.Sprintf("%d", i16) 78 | fmt.Sprintf("%v", i16) 79 | fmt.Sprint(i16) 80 | fmt.Sprintf("%d", int16(42)) 81 | fmt.Sprintf("%v", int16(42)) 82 | fmt.Sprint(int16(42)) 83 | fmt.Sprintf("%d", i32) 84 | fmt.Sprintf("%v", i32) 85 | fmt.Sprint(i32) 86 | fmt.Sprintf("%d", int32(42)) 87 | fmt.Sprintf("%v", int32(42)) 88 | fmt.Sprint(int32(42)) 89 | fmt.Sprintf("%d", i64) 90 | fmt.Sprintf("%v", i64) 91 | fmt.Sprint(i64) 92 | fmt.Sprintf("%d", int64(42)) 93 | fmt.Sprintf("%v", int64(42)) 94 | fmt.Sprint(int64(42)) 95 | 96 | var ui uint 97 | var ui8 uint8 98 | var ui16 uint16 99 | var ui32 uint32 100 | var ui64 uint64 101 | fmt.Sprintf("%d", ui) 102 | fmt.Sprintf("%v", ui) 103 | fmt.Sprint(ui) 104 | fmt.Sprintf("%d", uint(42)) 105 | fmt.Sprintf("%v", uint(42)) 106 | fmt.Sprint(uint(42)) 107 | fmt.Sprintf("%d", ui8) 108 | fmt.Sprintf("%v", ui8) 109 | fmt.Sprint(ui8) 110 | fmt.Sprintf("%d", uint8(42)) 111 | fmt.Sprintf("%v", uint8(42)) 112 | fmt.Sprint(uint8(42)) 113 | fmt.Sprintf("%d", ui16) 114 | fmt.Sprintf("%v", ui16) 115 | fmt.Sprint(ui16) 116 | fmt.Sprintf("%d", uint16(42)) 117 | fmt.Sprintf("%v", uint16(42)) 118 | fmt.Sprint(uint16(42)) 119 | fmt.Sprintf("%d", ui32) 120 | fmt.Sprintf("%v", ui32) 121 | fmt.Sprint(ui32) 122 | fmt.Sprintf("%d", uint32(42)) 123 | fmt.Sprintf("%v", uint32(42)) 124 | fmt.Sprint(uint32(42)) 125 | fmt.Sprintf("%d", ui64) 126 | fmt.Sprintf("%v", ui64) 127 | fmt.Sprintf("%x", ui64) 128 | fmt.Sprintf("%x", uint(42)) 129 | fmt.Sprint(ui64) 130 | fmt.Sprintf("%d", uint64(42)) 131 | fmt.Sprintf("%v", uint64(42)) 132 | fmt.Sprint(uint64(42)) 133 | } 134 | 135 | func suggestedFixesTest() { 136 | _ = func() string { 137 | if false { 138 | return fmt.Sprint("replace me") // want "string-format: fmt.Sprint can be replaced with just using the string" 139 | } 140 | return fmt.Sprintf("%s", "replace me") // want "string-format: fmt.Sprintf can be replaced with just using the string" 141 | } 142 | 143 | fmt.Println(fmt.Sprint(errSentinel)) 144 | fmt.Println(fmt.Sprintf("%s", errSentinel)) 145 | 146 | _ = func() string { 147 | switch 42 { 148 | case 1: 149 | return fmt.Sprint(false) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 150 | case 2: 151 | return fmt.Sprintf("%t", true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 152 | } 153 | return "" 154 | } 155 | 156 | var offset int 157 | params := url.Values{} 158 | params.Set("offset", fmt.Sprintf("%d", offset)) 159 | params.Set("offset", fmt.Sprint(offset)) 160 | 161 | var pubKey []byte 162 | if verifyPubKey := true; verifyPubKey { 163 | log.Println("pubkey=" + fmt.Sprintf("%x", pubKey)) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 164 | } 165 | 166 | var metaHash [16]byte 167 | fn := fmt.Sprintf("%s.%x", "coverage.MetaFilePref", metaHash) 168 | _ = "tmp." + fn + fmt.Sprintf("%d", time.Now().UnixNano()) 169 | _ = "tmp." + fn + fmt.Sprint(time.Now().UnixNano()) 170 | 171 | var change struct{ User struct{ ID uint } } 172 | var userStr string 173 | if id := change.User.ID; id != 0 { 174 | userStr = fmt.Sprintf("%d", id) 175 | userStr = fmt.Sprint(id) 176 | } 177 | _ = userStr 178 | } 179 | 180 | func negative() { 181 | const val = "val%d" 182 | 183 | _ = int32(42) 184 | 185 | fmt.Scan(42) 186 | fmt.Scanf("%d", 42) 187 | fmt.Println("%d", 42) 188 | fmt.Printf("%d") 189 | fmt.Printf("%v") 190 | fmt.Printf("%d", 42) 191 | fmt.Printf("%s %d", "hello", 42) 192 | fmt.Errorf("this is %s", "complex") 193 | 194 | fmt.Fprint(os.Stdout, "%d", 42) 195 | fmt.Fprintf(os.Stdout, "test") 196 | fmt.Fprintf(os.Stdout, "%d") 197 | fmt.Fprintf(os.Stdout, "%v") 198 | fmt.Fprintf(os.Stdout, "%d", 42) 199 | fmt.Fprintf(os.Stdout, "%s %d", "hello", 42) 200 | 201 | fmt.Sprint("test", 42) 202 | fmt.Sprint(42, 42) 203 | fmt.Sprintf("%d", 42, 42) 204 | fmt.Sprintf("%#d", 42) 205 | fmt.Sprintf("value %d", 42) 206 | fmt.Sprintf(val, 42) 207 | fmt.Sprintf("%s %v", "hello", "world") 208 | fmt.Sprintf("%#v", 42) 209 | fmt.Sprintf("%T", struct{ string }{}) 210 | fmt.Sprintf("%%v", 42) 211 | fmt.Sprintf("%3d", 42) 212 | fmt.Sprintf("% d", 42) 213 | fmt.Sprintf("%-10d", 42) 214 | fmt.Sprintf("%s %[1]s", "hello") 215 | fmt.Sprintf("%[1]s %[1]s", "hello") 216 | fmt.Sprintf("%[2]d %[1]d\n", 11, 22) 217 | fmt.Sprintf("%[3]*.[2]*[1]f", 12.0, 2, 6) 218 | fmt.Sprintf("%d %d %#[1]x %#x", 16, 17) 219 | 220 | // Integer. 221 | fmt.Sprintf("%#x", uint64(42)) 222 | fmt.Sprintf("%#v", uint64(42)) 223 | fmt.Sprintf("%#b", 42) 224 | fmt.Sprintf("%#o", 42) 225 | fmt.Sprintf("%#x", 42) 226 | fmt.Sprintf("%#X", 42) 227 | 228 | fmt.Sprintf("%b", 42) 229 | fmt.Sprintf("%c", 42) 230 | fmt.Sprintf("%o", 42) 231 | fmt.Sprintf("%O", 42) 232 | fmt.Sprintf("%q", 42) 233 | fmt.Sprintf("%x", 42) 234 | fmt.Sprintf("%X", 42) 235 | 236 | // Floating point. 237 | fmt.Sprintf("%9f", 42.42) 238 | fmt.Sprintf("%.2f", 42.42) 239 | fmt.Sprintf("%.2f", 42.42) 240 | fmt.Sprintf("%9.2f", 42.42) 241 | fmt.Sprintf("%9.f", 42.42) 242 | fmt.Sprintf("%.3g", 42.42) 243 | 244 | fmt.Sprintf("%b", float32(42.42)) 245 | fmt.Sprintf("%e", float32(42.42)) 246 | fmt.Sprintf("%E", float32(42.42)) 247 | fmt.Sprintf("%f", float32(42.42)) 248 | fmt.Sprintf("%F", float32(42.42)) 249 | fmt.Sprintf("%g", float32(42.42)) 250 | fmt.Sprintf("%G", float32(42.42)) 251 | fmt.Sprintf("%x", float32(42.42)) 252 | fmt.Sprintf("%X", float32(42.42)) 253 | fmt.Sprintf("%v", float32(42.42)) 254 | 255 | fmt.Sprintf("%b", 42.42) 256 | fmt.Sprintf("%e", 42.42) 257 | fmt.Sprintf("%E", 42.42) 258 | fmt.Sprintf("%f", 42.42) 259 | fmt.Sprintf("%F", 42.42) 260 | fmt.Sprintf("%g", 42.42) 261 | fmt.Sprintf("%G", 42.42) 262 | fmt.Sprintf("%x", 42.42) 263 | fmt.Sprintf("%X", 42.42) 264 | fmt.Sprintf("%v", 42.42) 265 | 266 | fmt.Sprintf("%b", 42i+42) 267 | fmt.Sprintf("%e", 42i+42) 268 | fmt.Sprintf("%E", 42i+42) 269 | fmt.Sprintf("%f", 42i+42) 270 | fmt.Sprintf("%F", 42i+42) 271 | fmt.Sprintf("%g", 42i+42) 272 | fmt.Sprintf("%G", 42i+42) 273 | fmt.Sprintf("%x", 42i+42) 274 | fmt.Sprintf("%X", 42i+42) 275 | fmt.Sprintf("%v", 42i+42) 276 | 277 | // String & slice of bytes. 278 | fmt.Sprintf("%q", "hello") 279 | fmt.Sprintf("%#q", `"hello"`) 280 | fmt.Sprintf("%+q", "hello") 281 | fmt.Sprintf("%X", "hello") 282 | 283 | // Slice. 284 | fmt.Sprintf("%x", []uint16{'d'}) 285 | fmt.Sprintf("%x", []uint32{'d'}) 286 | fmt.Sprintf("%x", []uint64{'d'}) 287 | fmt.Sprintf("%x", []uint{'d'}) 288 | fmt.Sprintf("%x", [1]byte{'c'}) 289 | fmt.Sprintf("%x", [1]uint8{'d'}) 290 | fmt.Sprintf("%x", [1]uint16{'d'}) 291 | fmt.Sprintf("%x", [1]uint32{'d'}) 292 | fmt.Sprintf("%x", [1]uint64{'d'}) 293 | fmt.Sprintf("%x", [1]uint{'d'}) 294 | fmt.Sprintf("%x", []int8{1}) 295 | fmt.Sprintf("%x", []int16{1}) 296 | fmt.Sprintf("%x", []int32{1}) 297 | fmt.Sprintf("%x", []int64{1}) 298 | fmt.Sprintf("%x", []int{1}) 299 | fmt.Sprintf("%x", [...]int8{1}) 300 | fmt.Sprintf("%x", [...]int16{1}) 301 | fmt.Sprintf("%x", [...]int32{1}) 302 | fmt.Sprintf("%x", [...]int64{1}) 303 | fmt.Sprintf("%x", [...]int{1}) 304 | fmt.Sprintf("%x", []string{"hello"}) 305 | fmt.Sprintf("%x", []rune{'a'}) 306 | 307 | fmt.Sprintf("% x", []byte{1, 2, 3}) 308 | fmt.Sprintf("% X", []byte{1, 2, 3}) 309 | fmt.Sprintf("%p", []byte{1, 2, 3}) 310 | fmt.Sprintf("%#p", []byte{1, 2, 3}) 311 | 312 | // Pointer. 313 | var ptr *int 314 | fmt.Sprintf("%v", ptr) 315 | fmt.Sprintf("%b", ptr) 316 | fmt.Sprintf("%d", ptr) 317 | fmt.Sprintf("%o", ptr) 318 | fmt.Sprintf("%x", ptr) 319 | fmt.Sprintf("%X", ptr) 320 | } 321 | 322 | func malformed() { 323 | fmt.Sprintf("%d", "example") 324 | fmt.Sprintf("%T", "example") 325 | fmt.Sprintf("%t", "example") 326 | fmt.Sprintf("%b", "example") 327 | fmt.Sprintf("%e", "example") 328 | fmt.Sprintf("%E", "example") 329 | fmt.Sprintf("%f", "example") 330 | fmt.Sprintf("%F", "example") 331 | fmt.Sprintf("%g", "example") 332 | fmt.Sprintf("%G", "example") 333 | fmt.Sprintf("%x", "example") 334 | fmt.Sprintf("%X", "example") 335 | 336 | fmt.Sprintf("%d", errSentinel) 337 | fmt.Sprintf("%T", errSentinel) 338 | fmt.Sprintf("%t", errSentinel) 339 | fmt.Sprintf("%b", errSentinel) 340 | fmt.Sprintf("%e", errSentinel) 341 | fmt.Sprintf("%E", errSentinel) 342 | fmt.Sprintf("%f", errSentinel) 343 | fmt.Sprintf("%F", errSentinel) 344 | fmt.Sprintf("%g", errSentinel) 345 | fmt.Sprintf("%G", errSentinel) 346 | fmt.Sprintf("%x", errSentinel) 347 | fmt.Sprintf("%X", errSentinel) 348 | 349 | fmt.Sprintf("%d", true) 350 | fmt.Sprintf("%T", true) 351 | fmt.Sprintf("%b", true) 352 | fmt.Sprintf("%e", true) 353 | fmt.Sprintf("%E", true) 354 | fmt.Sprintf("%f", true) 355 | fmt.Sprintf("%F", true) 356 | fmt.Sprintf("%g", true) 357 | fmt.Sprintf("%G", true) 358 | fmt.Sprintf("%x", true) 359 | fmt.Sprintf("%X", true) 360 | 361 | var bb []byte 362 | fmt.Sprintf("%d", bb) 363 | fmt.Sprintf("%T", bb) 364 | fmt.Sprintf("%t", bb) 365 | fmt.Sprintf("%b", bb) 366 | fmt.Sprintf("%e", bb) 367 | fmt.Sprintf("%E", bb) 368 | fmt.Sprintf("%f", bb) 369 | fmt.Sprintf("%F", bb) 370 | fmt.Sprintf("%g", bb) 371 | fmt.Sprintf("%G", bb) 372 | fmt.Sprintf("%X", bb) 373 | fmt.Sprintf("%v", bb) 374 | 375 | fmt.Sprintf("%T", 42) 376 | fmt.Sprintf("%t", 42) 377 | fmt.Sprintf("%b", 42) 378 | fmt.Sprintf("%e", 42) 379 | fmt.Sprintf("%E", 42) 380 | fmt.Sprintf("%f", 42) 381 | fmt.Sprintf("%F", 42) 382 | fmt.Sprintf("%g", 42) 383 | fmt.Sprintf("%G", 42) 384 | fmt.Sprintf("%x", 42) 385 | fmt.Sprintf("%X", 42) 386 | 387 | fmt.Sprintf("%T", uint(42)) 388 | fmt.Sprintf("%t", uint(42)) 389 | fmt.Sprintf("%b", uint(42)) 390 | fmt.Sprintf("%e", uint(42)) 391 | fmt.Sprintf("%E", uint(42)) 392 | fmt.Sprintf("%f", uint(42)) 393 | fmt.Sprintf("%F", uint(42)) 394 | fmt.Sprintf("%g", uint(42)) 395 | fmt.Sprintf("%G", uint(42)) 396 | fmt.Sprintf("%X", uint(42)) 397 | 398 | fmt.Sprintf("%d", 42.42) 399 | fmt.Sprintf("%d", map[string]string{}) 400 | fmt.Sprint(make(chan int)) 401 | fmt.Sprint([]int{1, 2, 3}) 402 | } 403 | -------------------------------------------------------------------------------- /analyzer/testdata/src/without-int-conversion/p.go: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | import ( // want "Fix imports" 4 | "errors" 5 | "fmt" 6 | "io" 7 | "log" 8 | "net/url" 9 | "os" 10 | "strconv" 11 | "time" 12 | ) 13 | 14 | var errSentinel = errors.New("connection refused") 15 | 16 | func positive() { 17 | var s string 18 | fmt.Sprintf("%s", "hello") // want "string-format: fmt.Sprintf can be replaced with just using the string" 19 | fmt.Sprintf("%v", "hello") // want "string-format: fmt.Sprintf can be replaced with just using the string" 20 | fmt.Sprintf("hello") // want "string-format: fmt.Sprintf can be replaced with just using the string" 21 | fmt.Sprint("hello") // want "string-format: fmt.Sprint can be replaced with just using the string" 22 | fmt.Sprintf("%s", s) // want "string-format: fmt.Sprintf can be replaced with just using the string" 23 | fmt.Sprintf("%[1]s", s) // want "string-format: fmt.Sprintf can be replaced with just using the string" 24 | fmt.Sprintf("%v", s) // want "string-format: fmt.Sprintf can be replaced with just using the string" 25 | fmt.Sprint(s) // want "string-format: fmt.Sprint can be replaced with just using the string" 26 | fmt.Errorf("hello") // want "error-format: fmt.Errorf can be replaced with errors.New" 27 | 28 | fmt.Sprintf("Hello %s", s) // want "string-format: fmt.Sprintf can be replaced with string concatenation" 29 | fmt.Sprintf("%s says Hello", s) // want "string-format: fmt.Sprintf can be replaced with string concatenation" 30 | fmt.Sprintf("Hello says %[1]s", s) // want "string-format: fmt.Sprintf can be replaced with string concatenation" 31 | 32 | var err error 33 | fmt.Sprintf("%s", errSentinel) 34 | fmt.Sprintf("%v", errSentinel) 35 | fmt.Sprint(errSentinel) 36 | fmt.Sprintf("%s", io.EOF) 37 | fmt.Sprintf("%v", io.EOF) 38 | fmt.Sprint(io.EOF) 39 | fmt.Sprintf("%s", err) 40 | fmt.Sprintf("%v", err) 41 | fmt.Sprint(err) 42 | 43 | var b bool 44 | fmt.Sprintf("%t", true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 45 | fmt.Sprintf("%v", true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 46 | fmt.Sprint(true) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 47 | fmt.Sprintf("%t", false) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 48 | fmt.Sprintf("%v", false) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 49 | fmt.Sprint(false) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 50 | fmt.Sprintf("%t", b) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 51 | fmt.Sprintf("%v", b) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 52 | fmt.Sprint(b) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 53 | 54 | var bs []byte 55 | var ba [3]byte 56 | fmt.Sprintf("%x", []byte{'a'}) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 57 | fmt.Sprintf("%x", []uint8{'b'}) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 58 | fmt.Sprintf("%x", bs) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 59 | fmt.Sprintf("%x", ba) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 60 | 61 | var i int 62 | var i8 int8 63 | var i16 int16 64 | var i32 int32 65 | var i64 int64 66 | fmt.Sprintf("%d", i) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 67 | fmt.Sprintf("%v", i) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 68 | fmt.Sprint(i) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 69 | fmt.Sprintf("%d", 42) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 70 | fmt.Sprintf("%v", 42) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 71 | fmt.Sprint(42) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 72 | fmt.Sprintf("%d", i8) 73 | fmt.Sprintf("%v", i8) 74 | fmt.Sprint(i8) 75 | fmt.Sprintf("%d", int8(42)) 76 | fmt.Sprintf("%v", int8(42)) 77 | fmt.Sprint(int8(42)) 78 | fmt.Sprintf("%d", i16) 79 | fmt.Sprintf("%v", i16) 80 | fmt.Sprint(i16) 81 | fmt.Sprintf("%d", int16(42)) 82 | fmt.Sprintf("%v", int16(42)) 83 | fmt.Sprint(int16(42)) 84 | fmt.Sprintf("%d", i32) 85 | fmt.Sprintf("%v", i32) 86 | fmt.Sprint(i32) 87 | fmt.Sprintf("%d", int32(42)) 88 | fmt.Sprintf("%v", int32(42)) 89 | fmt.Sprint(int32(42)) 90 | fmt.Sprintf("%d", i64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 91 | fmt.Sprintf("%v", i64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 92 | fmt.Sprint(i64) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 93 | fmt.Sprintf("%d", int64(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 94 | fmt.Sprintf("%v", int64(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 95 | fmt.Sprint(int64(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 96 | 97 | var ui uint 98 | var ui8 uint8 99 | var ui16 uint16 100 | var ui32 uint32 101 | var ui64 uint64 102 | fmt.Sprintf("%d", ui) 103 | fmt.Sprintf("%v", ui) 104 | fmt.Sprint(ui) 105 | fmt.Sprintf("%d", uint(42)) 106 | fmt.Sprintf("%v", uint(42)) 107 | fmt.Sprint(uint(42)) 108 | fmt.Sprintf("%d", ui8) 109 | fmt.Sprintf("%v", ui8) 110 | fmt.Sprint(ui8) 111 | fmt.Sprintf("%d", uint8(42)) 112 | fmt.Sprintf("%v", uint8(42)) 113 | fmt.Sprint(uint8(42)) 114 | fmt.Sprintf("%d", ui16) 115 | fmt.Sprintf("%v", ui16) 116 | fmt.Sprint(ui16) 117 | fmt.Sprintf("%d", uint16(42)) 118 | fmt.Sprintf("%v", uint16(42)) 119 | fmt.Sprint(uint16(42)) 120 | fmt.Sprintf("%d", ui32) 121 | fmt.Sprintf("%v", ui32) 122 | fmt.Sprint(ui32) 123 | fmt.Sprintf("%d", uint32(42)) 124 | fmt.Sprintf("%v", uint32(42)) 125 | fmt.Sprint(uint32(42)) 126 | fmt.Sprintf("%d", ui64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 127 | fmt.Sprintf("%v", ui64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 128 | fmt.Sprintf("%x", ui64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 129 | fmt.Sprintf("%x", uint(42)) 130 | fmt.Sprint(ui64) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 131 | fmt.Sprintf("%d", uint64(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 132 | fmt.Sprintf("%v", uint64(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 133 | fmt.Sprint(uint64(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 134 | } 135 | 136 | func suggestedFixesTest() { 137 | _ = func() string { 138 | if false { 139 | return fmt.Sprint("replace me") // want "string-format: fmt.Sprint can be replaced with just using the string" 140 | } 141 | return fmt.Sprintf("%s", "replace me") // want "string-format: fmt.Sprintf can be replaced with just using the string" 142 | } 143 | 144 | fmt.Println(fmt.Sprint(errSentinel)) 145 | fmt.Println(fmt.Sprintf("%s", errSentinel)) 146 | 147 | _ = func() string { 148 | switch 42 { 149 | case 1: 150 | return fmt.Sprint(false) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 151 | case 2: 152 | return fmt.Sprintf("%t", true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 153 | } 154 | return "" 155 | } 156 | 157 | var offset int 158 | params := url.Values{} 159 | params.Set("offset", strconv.Itoa(offset)) 160 | params.Set("offset", strconv.Itoa(offset)) 161 | 162 | var pubKey []byte 163 | if verifyPubKey := true; verifyPubKey { 164 | log.Println("pubkey=" + fmt.Sprintf("%x", pubKey)) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 165 | } 166 | 167 | var metaHash [16]byte 168 | fn := fmt.Sprintf("%s.%x", "coverage.MetaFilePref", metaHash) 169 | _ = "tmp." + fn + fmt.Sprintf("%d", time.Now().UnixNano()) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 170 | _ = "tmp." + fn + fmt.Sprint(time.Now().UnixNano()) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 171 | 172 | var change struct{ User struct{ ID uint } } 173 | var userStr string 174 | if id := change.User.ID; id != 0 { 175 | userStr = fmt.Sprintf("%d", id) 176 | userStr = fmt.Sprint(id) 177 | } 178 | _ = userStr 179 | } 180 | 181 | func negative() { 182 | const val = "val%d" 183 | 184 | _ = int32(42) 185 | 186 | fmt.Scan(42) 187 | fmt.Scanf("%d", 42) 188 | fmt.Println("%d", 42) 189 | fmt.Printf("%d") 190 | fmt.Printf("%v") 191 | fmt.Printf("%d", 42) 192 | fmt.Printf("%s %d", "hello", 42) 193 | fmt.Errorf("this is %s", "complex") 194 | 195 | fmt.Fprint(os.Stdout, "%d", 42) 196 | fmt.Fprintf(os.Stdout, "test") 197 | fmt.Fprintf(os.Stdout, "%d") 198 | fmt.Fprintf(os.Stdout, "%v") 199 | fmt.Fprintf(os.Stdout, "%d", 42) 200 | fmt.Fprintf(os.Stdout, "%s %d", "hello", 42) 201 | 202 | fmt.Sprint("test", 42) 203 | fmt.Sprint(42, 42) 204 | fmt.Sprintf("%d", 42, 42) 205 | fmt.Sprintf("%#d", 42) 206 | fmt.Sprintf("value %d", 42) 207 | fmt.Sprintf(val, 42) 208 | fmt.Sprintf("%s %v", "hello", "world") 209 | fmt.Sprintf("%#v", 42) 210 | fmt.Sprintf("%T", struct{ string }{}) 211 | fmt.Sprintf("%%v", 42) 212 | fmt.Sprintf("%3d", 42) 213 | fmt.Sprintf("% d", 42) 214 | fmt.Sprintf("%-10d", 42) 215 | fmt.Sprintf("%s %[1]s", "hello") 216 | fmt.Sprintf("%[1]s %[1]s", "hello") 217 | fmt.Sprintf("%[2]d %[1]d\n", 11, 22) 218 | fmt.Sprintf("%[3]*.[2]*[1]f", 12.0, 2, 6) 219 | fmt.Sprintf("%d %d %#[1]x %#x", 16, 17) 220 | 221 | // Integer. 222 | fmt.Sprintf("%#x", uint64(42)) 223 | fmt.Sprintf("%#v", uint64(42)) 224 | fmt.Sprintf("%#b", 42) 225 | fmt.Sprintf("%#o", 42) 226 | fmt.Sprintf("%#x", 42) 227 | fmt.Sprintf("%#X", 42) 228 | 229 | fmt.Sprintf("%b", 42) 230 | fmt.Sprintf("%c", 42) 231 | fmt.Sprintf("%o", 42) 232 | fmt.Sprintf("%O", 42) 233 | fmt.Sprintf("%q", 42) 234 | fmt.Sprintf("%x", 42) 235 | fmt.Sprintf("%X", 42) 236 | 237 | // Floating point. 238 | fmt.Sprintf("%9f", 42.42) 239 | fmt.Sprintf("%.2f", 42.42) 240 | fmt.Sprintf("%.2f", 42.42) 241 | fmt.Sprintf("%9.2f", 42.42) 242 | fmt.Sprintf("%9.f", 42.42) 243 | fmt.Sprintf("%.3g", 42.42) 244 | 245 | fmt.Sprintf("%b", float32(42.42)) 246 | fmt.Sprintf("%e", float32(42.42)) 247 | fmt.Sprintf("%E", float32(42.42)) 248 | fmt.Sprintf("%f", float32(42.42)) 249 | fmt.Sprintf("%F", float32(42.42)) 250 | fmt.Sprintf("%g", float32(42.42)) 251 | fmt.Sprintf("%G", float32(42.42)) 252 | fmt.Sprintf("%x", float32(42.42)) 253 | fmt.Sprintf("%X", float32(42.42)) 254 | fmt.Sprintf("%v", float32(42.42)) 255 | 256 | fmt.Sprintf("%b", 42.42) 257 | fmt.Sprintf("%e", 42.42) 258 | fmt.Sprintf("%E", 42.42) 259 | fmt.Sprintf("%f", 42.42) 260 | fmt.Sprintf("%F", 42.42) 261 | fmt.Sprintf("%g", 42.42) 262 | fmt.Sprintf("%G", 42.42) 263 | fmt.Sprintf("%x", 42.42) 264 | fmt.Sprintf("%X", 42.42) 265 | fmt.Sprintf("%v", 42.42) 266 | 267 | fmt.Sprintf("%b", 42i+42) 268 | fmt.Sprintf("%e", 42i+42) 269 | fmt.Sprintf("%E", 42i+42) 270 | fmt.Sprintf("%f", 42i+42) 271 | fmt.Sprintf("%F", 42i+42) 272 | fmt.Sprintf("%g", 42i+42) 273 | fmt.Sprintf("%G", 42i+42) 274 | fmt.Sprintf("%x", 42i+42) 275 | fmt.Sprintf("%X", 42i+42) 276 | fmt.Sprintf("%v", 42i+42) 277 | 278 | // String & slice of bytes. 279 | fmt.Sprintf("%q", "hello") 280 | fmt.Sprintf("%#q", `"hello"`) 281 | fmt.Sprintf("%+q", "hello") 282 | fmt.Sprintf("%X", "hello") 283 | 284 | // Slice. 285 | fmt.Sprintf("%x", []uint16{'d'}) 286 | fmt.Sprintf("%x", []uint32{'d'}) 287 | fmt.Sprintf("%x", []uint64{'d'}) 288 | fmt.Sprintf("%x", []uint{'d'}) 289 | fmt.Sprintf("%x", [1]byte{'c'}) 290 | fmt.Sprintf("%x", [1]uint8{'d'}) 291 | fmt.Sprintf("%x", [1]uint16{'d'}) 292 | fmt.Sprintf("%x", [1]uint32{'d'}) 293 | fmt.Sprintf("%x", [1]uint64{'d'}) 294 | fmt.Sprintf("%x", [1]uint{'d'}) 295 | fmt.Sprintf("%x", []int8{1}) 296 | fmt.Sprintf("%x", []int16{1}) 297 | fmt.Sprintf("%x", []int32{1}) 298 | fmt.Sprintf("%x", []int64{1}) 299 | fmt.Sprintf("%x", []int{1}) 300 | fmt.Sprintf("%x", [...]int8{1}) 301 | fmt.Sprintf("%x", [...]int16{1}) 302 | fmt.Sprintf("%x", [...]int32{1}) 303 | fmt.Sprintf("%x", [...]int64{1}) 304 | fmt.Sprintf("%x", [...]int{1}) 305 | fmt.Sprintf("%x", []string{"hello"}) 306 | fmt.Sprintf("%x", []rune{'a'}) 307 | 308 | fmt.Sprintf("% x", []byte{1, 2, 3}) 309 | fmt.Sprintf("% X", []byte{1, 2, 3}) 310 | fmt.Sprintf("%p", []byte{1, 2, 3}) 311 | fmt.Sprintf("%#p", []byte{1, 2, 3}) 312 | 313 | // Pointer. 314 | var ptr *int 315 | fmt.Sprintf("%v", ptr) 316 | fmt.Sprintf("%b", ptr) 317 | fmt.Sprintf("%d", ptr) 318 | fmt.Sprintf("%o", ptr) 319 | fmt.Sprintf("%x", ptr) 320 | fmt.Sprintf("%X", ptr) 321 | } 322 | 323 | func malformed() { 324 | fmt.Sprintf("%d", "example") 325 | fmt.Sprintf("%T", "example") 326 | fmt.Sprintf("%t", "example") 327 | fmt.Sprintf("%b", "example") 328 | fmt.Sprintf("%e", "example") 329 | fmt.Sprintf("%E", "example") 330 | fmt.Sprintf("%f", "example") 331 | fmt.Sprintf("%F", "example") 332 | fmt.Sprintf("%g", "example") 333 | fmt.Sprintf("%G", "example") 334 | fmt.Sprintf("%x", "example") 335 | fmt.Sprintf("%X", "example") 336 | 337 | fmt.Sprintf("%d", errSentinel) 338 | fmt.Sprintf("%T", errSentinel) 339 | fmt.Sprintf("%t", errSentinel) 340 | fmt.Sprintf("%b", errSentinel) 341 | fmt.Sprintf("%e", errSentinel) 342 | fmt.Sprintf("%E", errSentinel) 343 | fmt.Sprintf("%f", errSentinel) 344 | fmt.Sprintf("%F", errSentinel) 345 | fmt.Sprintf("%g", errSentinel) 346 | fmt.Sprintf("%G", errSentinel) 347 | fmt.Sprintf("%x", errSentinel) 348 | fmt.Sprintf("%X", errSentinel) 349 | 350 | fmt.Sprintf("%d", true) 351 | fmt.Sprintf("%T", true) 352 | fmt.Sprintf("%b", true) 353 | fmt.Sprintf("%e", true) 354 | fmt.Sprintf("%E", true) 355 | fmt.Sprintf("%f", true) 356 | fmt.Sprintf("%F", true) 357 | fmt.Sprintf("%g", true) 358 | fmt.Sprintf("%G", true) 359 | fmt.Sprintf("%x", true) 360 | fmt.Sprintf("%X", true) 361 | 362 | var bb []byte 363 | fmt.Sprintf("%d", bb) 364 | fmt.Sprintf("%T", bb) 365 | fmt.Sprintf("%t", bb) 366 | fmt.Sprintf("%b", bb) 367 | fmt.Sprintf("%e", bb) 368 | fmt.Sprintf("%E", bb) 369 | fmt.Sprintf("%f", bb) 370 | fmt.Sprintf("%F", bb) 371 | fmt.Sprintf("%g", bb) 372 | fmt.Sprintf("%G", bb) 373 | fmt.Sprintf("%X", bb) 374 | fmt.Sprintf("%v", bb) 375 | 376 | fmt.Sprintf("%T", 42) 377 | fmt.Sprintf("%t", 42) 378 | fmt.Sprintf("%b", 42) 379 | fmt.Sprintf("%e", 42) 380 | fmt.Sprintf("%E", 42) 381 | fmt.Sprintf("%f", 42) 382 | fmt.Sprintf("%F", 42) 383 | fmt.Sprintf("%g", 42) 384 | fmt.Sprintf("%G", 42) 385 | fmt.Sprintf("%x", 42) 386 | fmt.Sprintf("%X", 42) 387 | 388 | fmt.Sprintf("%T", uint(42)) 389 | fmt.Sprintf("%t", uint(42)) 390 | fmt.Sprintf("%b", uint(42)) 391 | fmt.Sprintf("%e", uint(42)) 392 | fmt.Sprintf("%E", uint(42)) 393 | fmt.Sprintf("%f", uint(42)) 394 | fmt.Sprintf("%F", uint(42)) 395 | fmt.Sprintf("%g", uint(42)) 396 | fmt.Sprintf("%G", uint(42)) 397 | fmt.Sprintf("%x", uint(42)) 398 | fmt.Sprintf("%X", uint(42)) 399 | 400 | fmt.Sprintf("%d", 42.42) 401 | fmt.Sprintf("%d", map[string]string{}) 402 | fmt.Sprint(make(chan int)) 403 | fmt.Sprint([]int{1, 2, 3}) 404 | } 405 | -------------------------------------------------------------------------------- /analyzer/testdata/src/without-int-conversion/p.go.golden: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | import ( // want "Fix imports" 4 | "encoding/hex" 5 | "errors" 6 | "fmt" 7 | "io" 8 | "log" 9 | "net/url" 10 | "os" 11 | "strconv" 12 | "time" 13 | ) 14 | 15 | var errSentinel = errors.New("connection refused") 16 | 17 | func positive() { 18 | var s string 19 | "hello" // want "string-format: fmt.Sprintf can be replaced with just using the string" 20 | "hello" // want "string-format: fmt.Sprintf can be replaced with just using the string" 21 | "hello" // want "string-format: fmt.Sprintf can be replaced with just using the string" 22 | "hello" // want "string-format: fmt.Sprint can be replaced with just using the string" 23 | s // want "string-format: fmt.Sprintf can be replaced with just using the string" 24 | s // want "string-format: fmt.Sprintf can be replaced with just using the string" 25 | s // want "string-format: fmt.Sprintf can be replaced with just using the string" 26 | s // want "string-format: fmt.Sprint can be replaced with just using the string" 27 | errors.New("hello") // want "error-format: fmt.Errorf can be replaced with errors.New" 28 | 29 | "Hello " + s // want "string-format: fmt.Sprintf can be replaced with string concatenation" 30 | s + " says Hello" // want "string-format: fmt.Sprintf can be replaced with string concatenation" 31 | "Hello says " + s // want "string-format: fmt.Sprintf can be replaced with string concatenation" 32 | 33 | var err error 34 | fmt.Sprintf("%s", errSentinel) 35 | fmt.Sprintf("%v", errSentinel) 36 | fmt.Sprint(errSentinel) 37 | fmt.Sprintf("%s", io.EOF) 38 | fmt.Sprintf("%v", io.EOF) 39 | fmt.Sprint(io.EOF) 40 | fmt.Sprintf("%s", err) 41 | fmt.Sprintf("%v", err) 42 | fmt.Sprint(err) 43 | 44 | var b bool 45 | strconv.FormatBool(true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 46 | strconv.FormatBool(true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 47 | strconv.FormatBool(true) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 48 | strconv.FormatBool(false) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 49 | strconv.FormatBool(false) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 50 | strconv.FormatBool(false) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 51 | strconv.FormatBool(b) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 52 | strconv.FormatBool(b) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 53 | strconv.FormatBool(b) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 54 | 55 | var bs []byte 56 | var ba [3]byte 57 | hex.EncodeToString([]byte{'a'}) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 58 | hex.EncodeToString([]uint8{'b'}) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 59 | hex.EncodeToString(bs) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 60 | hex.EncodeToString(ba[:]) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 61 | 62 | var i int 63 | var i8 int8 64 | var i16 int16 65 | var i32 int32 66 | var i64 int64 67 | strconv.Itoa(i) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 68 | strconv.Itoa(i) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 69 | strconv.Itoa(i) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 70 | strconv.Itoa(42) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 71 | strconv.Itoa(42) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 72 | strconv.Itoa(42) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 73 | fmt.Sprintf("%d", i8) 74 | fmt.Sprintf("%v", i8) 75 | fmt.Sprint(i8) 76 | fmt.Sprintf("%d", int8(42)) 77 | fmt.Sprintf("%v", int8(42)) 78 | fmt.Sprint(int8(42)) 79 | fmt.Sprintf("%d", i16) 80 | fmt.Sprintf("%v", i16) 81 | fmt.Sprint(i16) 82 | fmt.Sprintf("%d", int16(42)) 83 | fmt.Sprintf("%v", int16(42)) 84 | fmt.Sprint(int16(42)) 85 | fmt.Sprintf("%d", i32) 86 | fmt.Sprintf("%v", i32) 87 | fmt.Sprint(i32) 88 | fmt.Sprintf("%d", int32(42)) 89 | fmt.Sprintf("%v", int32(42)) 90 | fmt.Sprint(int32(42)) 91 | strconv.FormatInt(i64, 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 92 | strconv.FormatInt(i64, 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 93 | strconv.FormatInt(i64, 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 94 | strconv.FormatInt(int64(42), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 95 | strconv.FormatInt(int64(42), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 96 | strconv.FormatInt(int64(42), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 97 | 98 | var ui uint 99 | var ui8 uint8 100 | var ui16 uint16 101 | var ui32 uint32 102 | var ui64 uint64 103 | fmt.Sprintf("%d", ui) 104 | fmt.Sprintf("%v", ui) 105 | fmt.Sprint(ui) 106 | fmt.Sprintf("%d", uint(42)) 107 | fmt.Sprintf("%v", uint(42)) 108 | fmt.Sprint(uint(42)) 109 | fmt.Sprintf("%d", ui8) 110 | fmt.Sprintf("%v", ui8) 111 | fmt.Sprint(ui8) 112 | fmt.Sprintf("%d", uint8(42)) 113 | fmt.Sprintf("%v", uint8(42)) 114 | fmt.Sprint(uint8(42)) 115 | fmt.Sprintf("%d", ui16) 116 | fmt.Sprintf("%v", ui16) 117 | fmt.Sprint(ui16) 118 | fmt.Sprintf("%d", uint16(42)) 119 | fmt.Sprintf("%v", uint16(42)) 120 | fmt.Sprint(uint16(42)) 121 | fmt.Sprintf("%d", ui32) 122 | fmt.Sprintf("%v", ui32) 123 | fmt.Sprint(ui32) 124 | fmt.Sprintf("%d", uint32(42)) 125 | fmt.Sprintf("%v", uint32(42)) 126 | fmt.Sprint(uint32(42)) 127 | strconv.FormatUint(ui64, 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 128 | strconv.FormatUint(ui64, 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 129 | strconv.FormatUint(ui64, 16) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 130 | fmt.Sprintf("%x", uint(42)) 131 | strconv.FormatUint(ui64, 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 132 | strconv.FormatUint(uint64(42), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 133 | strconv.FormatUint(uint64(42), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 134 | strconv.FormatUint(uint64(42), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 135 | } 136 | 137 | func suggestedFixesTest() { 138 | _ = func() string { 139 | if false { 140 | return "replace me" // want "string-format: fmt.Sprint can be replaced with just using the string" 141 | } 142 | return "replace me" // want "string-format: fmt.Sprintf can be replaced with just using the string" 143 | } 144 | 145 | fmt.Println(fmt.Sprint(errSentinel)) 146 | fmt.Println(fmt.Sprintf("%s", errSentinel)) 147 | 148 | _ = func() string { 149 | switch 42 { 150 | case 1: 151 | return strconv.FormatBool(false) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 152 | case 2: 153 | return strconv.FormatBool(true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 154 | } 155 | return "" 156 | } 157 | 158 | var offset int 159 | params := url.Values{} 160 | params.Set("offset", strconv.Itoa(offset)) 161 | params.Set("offset", strconv.Itoa(offset)) 162 | 163 | var pubKey []byte 164 | if verifyPubKey := true; verifyPubKey { 165 | log.Println("pubkey=" + hex.EncodeToString(pubKey)) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 166 | } 167 | 168 | var metaHash [16]byte 169 | fn := fmt.Sprintf("%s.%x", "coverage.MetaFilePref", metaHash) 170 | _ = "tmp." + fn + strconv.FormatInt(time.Now().UnixNano(), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 171 | _ = "tmp." + fn + strconv.FormatInt(time.Now().UnixNano(), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 172 | 173 | var change struct{ User struct{ ID uint } } 174 | var userStr string 175 | if id := change.User.ID; id != 0 { 176 | userStr = fmt.Sprintf("%d", id) 177 | userStr = fmt.Sprint(id) 178 | } 179 | _ = userStr 180 | } 181 | 182 | func negative() { 183 | const val = "val%d" 184 | 185 | _ = int32(42) 186 | 187 | fmt.Scan(42) 188 | fmt.Scanf("%d", 42) 189 | fmt.Println("%d", 42) 190 | fmt.Printf("%d") 191 | fmt.Printf("%v") 192 | fmt.Printf("%d", 42) 193 | fmt.Printf("%s %d", "hello", 42) 194 | fmt.Errorf("this is %s", "complex") 195 | 196 | fmt.Fprint(os.Stdout, "%d", 42) 197 | fmt.Fprintf(os.Stdout, "test") 198 | fmt.Fprintf(os.Stdout, "%d") 199 | fmt.Fprintf(os.Stdout, "%v") 200 | fmt.Fprintf(os.Stdout, "%d", 42) 201 | fmt.Fprintf(os.Stdout, "%s %d", "hello", 42) 202 | 203 | fmt.Sprint("test", 42) 204 | fmt.Sprint(42, 42) 205 | fmt.Sprintf("%d", 42, 42) 206 | fmt.Sprintf("%#d", 42) 207 | fmt.Sprintf("value %d", 42) 208 | fmt.Sprintf(val, 42) 209 | fmt.Sprintf("%s %v", "hello", "world") 210 | fmt.Sprintf("%#v", 42) 211 | fmt.Sprintf("%T", struct{ string }{}) 212 | fmt.Sprintf("%%v", 42) 213 | fmt.Sprintf("%3d", 42) 214 | fmt.Sprintf("% d", 42) 215 | fmt.Sprintf("%-10d", 42) 216 | fmt.Sprintf("%s %[1]s", "hello") 217 | fmt.Sprintf("%[1]s %[1]s", "hello") 218 | fmt.Sprintf("%[2]d %[1]d\n", 11, 22) 219 | fmt.Sprintf("%[3]*.[2]*[1]f", 12.0, 2, 6) 220 | fmt.Sprintf("%d %d %#[1]x %#x", 16, 17) 221 | 222 | // Integer. 223 | fmt.Sprintf("%#x", uint64(42)) 224 | fmt.Sprintf("%#v", uint64(42)) 225 | fmt.Sprintf("%#b", 42) 226 | fmt.Sprintf("%#o", 42) 227 | fmt.Sprintf("%#x", 42) 228 | fmt.Sprintf("%#X", 42) 229 | 230 | fmt.Sprintf("%b", 42) 231 | fmt.Sprintf("%c", 42) 232 | fmt.Sprintf("%o", 42) 233 | fmt.Sprintf("%O", 42) 234 | fmt.Sprintf("%q", 42) 235 | fmt.Sprintf("%x", 42) 236 | fmt.Sprintf("%X", 42) 237 | 238 | // Floating point. 239 | fmt.Sprintf("%9f", 42.42) 240 | fmt.Sprintf("%.2f", 42.42) 241 | fmt.Sprintf("%.2f", 42.42) 242 | fmt.Sprintf("%9.2f", 42.42) 243 | fmt.Sprintf("%9.f", 42.42) 244 | fmt.Sprintf("%.3g", 42.42) 245 | 246 | fmt.Sprintf("%b", float32(42.42)) 247 | fmt.Sprintf("%e", float32(42.42)) 248 | fmt.Sprintf("%E", float32(42.42)) 249 | fmt.Sprintf("%f", float32(42.42)) 250 | fmt.Sprintf("%F", float32(42.42)) 251 | fmt.Sprintf("%g", float32(42.42)) 252 | fmt.Sprintf("%G", float32(42.42)) 253 | fmt.Sprintf("%x", float32(42.42)) 254 | fmt.Sprintf("%X", float32(42.42)) 255 | fmt.Sprintf("%v", float32(42.42)) 256 | 257 | fmt.Sprintf("%b", 42.42) 258 | fmt.Sprintf("%e", 42.42) 259 | fmt.Sprintf("%E", 42.42) 260 | fmt.Sprintf("%f", 42.42) 261 | fmt.Sprintf("%F", 42.42) 262 | fmt.Sprintf("%g", 42.42) 263 | fmt.Sprintf("%G", 42.42) 264 | fmt.Sprintf("%x", 42.42) 265 | fmt.Sprintf("%X", 42.42) 266 | fmt.Sprintf("%v", 42.42) 267 | 268 | fmt.Sprintf("%b", 42i+42) 269 | fmt.Sprintf("%e", 42i+42) 270 | fmt.Sprintf("%E", 42i+42) 271 | fmt.Sprintf("%f", 42i+42) 272 | fmt.Sprintf("%F", 42i+42) 273 | fmt.Sprintf("%g", 42i+42) 274 | fmt.Sprintf("%G", 42i+42) 275 | fmt.Sprintf("%x", 42i+42) 276 | fmt.Sprintf("%X", 42i+42) 277 | fmt.Sprintf("%v", 42i+42) 278 | 279 | // String & slice of bytes. 280 | fmt.Sprintf("%q", "hello") 281 | fmt.Sprintf("%#q", `"hello"`) 282 | fmt.Sprintf("%+q", "hello") 283 | fmt.Sprintf("%X", "hello") 284 | 285 | // Slice. 286 | fmt.Sprintf("%x", []uint16{'d'}) 287 | fmt.Sprintf("%x", []uint32{'d'}) 288 | fmt.Sprintf("%x", []uint64{'d'}) 289 | fmt.Sprintf("%x", []uint{'d'}) 290 | fmt.Sprintf("%x", [1]byte{'c'}) 291 | fmt.Sprintf("%x", [1]uint8{'d'}) 292 | fmt.Sprintf("%x", [1]uint16{'d'}) 293 | fmt.Sprintf("%x", [1]uint32{'d'}) 294 | fmt.Sprintf("%x", [1]uint64{'d'}) 295 | fmt.Sprintf("%x", [1]uint{'d'}) 296 | fmt.Sprintf("%x", []int8{1}) 297 | fmt.Sprintf("%x", []int16{1}) 298 | fmt.Sprintf("%x", []int32{1}) 299 | fmt.Sprintf("%x", []int64{1}) 300 | fmt.Sprintf("%x", []int{1}) 301 | fmt.Sprintf("%x", [...]int8{1}) 302 | fmt.Sprintf("%x", [...]int16{1}) 303 | fmt.Sprintf("%x", [...]int32{1}) 304 | fmt.Sprintf("%x", [...]int64{1}) 305 | fmt.Sprintf("%x", [...]int{1}) 306 | fmt.Sprintf("%x", []string{"hello"}) 307 | fmt.Sprintf("%x", []rune{'a'}) 308 | 309 | fmt.Sprintf("% x", []byte{1, 2, 3}) 310 | fmt.Sprintf("% X", []byte{1, 2, 3}) 311 | fmt.Sprintf("%p", []byte{1, 2, 3}) 312 | fmt.Sprintf("%#p", []byte{1, 2, 3}) 313 | 314 | // Pointer. 315 | var ptr *int 316 | fmt.Sprintf("%v", ptr) 317 | fmt.Sprintf("%b", ptr) 318 | fmt.Sprintf("%d", ptr) 319 | fmt.Sprintf("%o", ptr) 320 | fmt.Sprintf("%x", ptr) 321 | fmt.Sprintf("%X", ptr) 322 | } 323 | 324 | func malformed() { 325 | fmt.Sprintf("%d", "example") 326 | fmt.Sprintf("%T", "example") 327 | fmt.Sprintf("%t", "example") 328 | fmt.Sprintf("%b", "example") 329 | fmt.Sprintf("%e", "example") 330 | fmt.Sprintf("%E", "example") 331 | fmt.Sprintf("%f", "example") 332 | fmt.Sprintf("%F", "example") 333 | fmt.Sprintf("%g", "example") 334 | fmt.Sprintf("%G", "example") 335 | fmt.Sprintf("%x", "example") 336 | fmt.Sprintf("%X", "example") 337 | 338 | fmt.Sprintf("%d", errSentinel) 339 | fmt.Sprintf("%T", errSentinel) 340 | fmt.Sprintf("%t", errSentinel) 341 | fmt.Sprintf("%b", errSentinel) 342 | fmt.Sprintf("%e", errSentinel) 343 | fmt.Sprintf("%E", errSentinel) 344 | fmt.Sprintf("%f", errSentinel) 345 | fmt.Sprintf("%F", errSentinel) 346 | fmt.Sprintf("%g", errSentinel) 347 | fmt.Sprintf("%G", errSentinel) 348 | fmt.Sprintf("%x", errSentinel) 349 | fmt.Sprintf("%X", errSentinel) 350 | 351 | fmt.Sprintf("%d", true) 352 | fmt.Sprintf("%T", true) 353 | fmt.Sprintf("%b", true) 354 | fmt.Sprintf("%e", true) 355 | fmt.Sprintf("%E", true) 356 | fmt.Sprintf("%f", true) 357 | fmt.Sprintf("%F", true) 358 | fmt.Sprintf("%g", true) 359 | fmt.Sprintf("%G", true) 360 | fmt.Sprintf("%x", true) 361 | fmt.Sprintf("%X", true) 362 | 363 | var bb []byte 364 | fmt.Sprintf("%d", bb) 365 | fmt.Sprintf("%T", bb) 366 | fmt.Sprintf("%t", bb) 367 | fmt.Sprintf("%b", bb) 368 | fmt.Sprintf("%e", bb) 369 | fmt.Sprintf("%E", bb) 370 | fmt.Sprintf("%f", bb) 371 | fmt.Sprintf("%F", bb) 372 | fmt.Sprintf("%g", bb) 373 | fmt.Sprintf("%G", bb) 374 | fmt.Sprintf("%X", bb) 375 | fmt.Sprintf("%v", bb) 376 | 377 | fmt.Sprintf("%T", 42) 378 | fmt.Sprintf("%t", 42) 379 | fmt.Sprintf("%b", 42) 380 | fmt.Sprintf("%e", 42) 381 | fmt.Sprintf("%E", 42) 382 | fmt.Sprintf("%f", 42) 383 | fmt.Sprintf("%F", 42) 384 | fmt.Sprintf("%g", 42) 385 | fmt.Sprintf("%G", 42) 386 | fmt.Sprintf("%x", 42) 387 | fmt.Sprintf("%X", 42) 388 | 389 | fmt.Sprintf("%T", uint(42)) 390 | fmt.Sprintf("%t", uint(42)) 391 | fmt.Sprintf("%b", uint(42)) 392 | fmt.Sprintf("%e", uint(42)) 393 | fmt.Sprintf("%E", uint(42)) 394 | fmt.Sprintf("%f", uint(42)) 395 | fmt.Sprintf("%F", uint(42)) 396 | fmt.Sprintf("%g", uint(42)) 397 | fmt.Sprintf("%G", uint(42)) 398 | fmt.Sprintf("%x", uint(42)) 399 | fmt.Sprintf("%X", uint(42)) 400 | 401 | fmt.Sprintf("%d", 42.42) 402 | fmt.Sprintf("%d", map[string]string{}) 403 | fmt.Sprint(make(chan int)) 404 | fmt.Sprint([]int{1, 2, 3}) 405 | } 406 | -------------------------------------------------------------------------------- /analyzer/testdata/src/without-string-format/p.go: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | import ( // want "Fix imports" 4 | "errors" 5 | "fmt" 6 | "io" 7 | "log" 8 | "net/url" 9 | "os" 10 | "time" 11 | ) 12 | 13 | var errSentinel = errors.New("connection refused") 14 | 15 | func positive() { 16 | var s string 17 | fmt.Sprintf("%s", "hello") 18 | fmt.Sprintf("%v", "hello") 19 | fmt.Sprintf("hello") 20 | fmt.Sprint("hello") 21 | fmt.Sprintf("%s", s) 22 | fmt.Sprintf("%[1]s", s) 23 | fmt.Sprintf("%v", s) 24 | fmt.Sprint(s) 25 | fmt.Errorf("hello") // want "error-format: fmt.Errorf can be replaced with errors.New" 26 | 27 | fmt.Sprintf("Hello %s", s) 28 | fmt.Sprintf("%s says Hello", s) 29 | fmt.Sprintf("Hello says %[1]s", s) 30 | 31 | var err error 32 | fmt.Sprintf("%s", errSentinel) 33 | fmt.Sprintf("%v", errSentinel) 34 | fmt.Sprint(errSentinel) 35 | fmt.Sprintf("%s", io.EOF) 36 | fmt.Sprintf("%v", io.EOF) 37 | fmt.Sprint(io.EOF) 38 | fmt.Sprintf("%s", err) 39 | fmt.Sprintf("%v", err) 40 | fmt.Sprint(err) 41 | 42 | var b bool 43 | fmt.Sprintf("%t", true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 44 | fmt.Sprintf("%v", true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 45 | fmt.Sprint(true) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 46 | fmt.Sprintf("%t", false) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 47 | fmt.Sprintf("%v", false) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 48 | fmt.Sprint(false) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 49 | fmt.Sprintf("%t", b) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 50 | fmt.Sprintf("%v", b) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 51 | fmt.Sprint(b) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 52 | 53 | var bs []byte 54 | var ba [3]byte 55 | fmt.Sprintf("%x", []byte{'a'}) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 56 | fmt.Sprintf("%x", []uint8{'b'}) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 57 | fmt.Sprintf("%x", bs) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 58 | fmt.Sprintf("%x", ba) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 59 | 60 | var i int 61 | var i8 int8 62 | var i16 int16 63 | var i32 int32 64 | var i64 int64 65 | fmt.Sprintf("%d", i) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 66 | fmt.Sprintf("%v", i) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 67 | fmt.Sprint(i) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 68 | fmt.Sprintf("%d", 42) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 69 | fmt.Sprintf("%v", 42) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 70 | fmt.Sprint(42) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 71 | fmt.Sprintf("%d", i8) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 72 | fmt.Sprintf("%v", i8) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 73 | fmt.Sprint(i8) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 74 | fmt.Sprintf("%d", int8(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 75 | fmt.Sprintf("%v", int8(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 76 | fmt.Sprint(int8(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 77 | fmt.Sprintf("%d", i16) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 78 | fmt.Sprintf("%v", i16) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 79 | fmt.Sprint(i16) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 80 | fmt.Sprintf("%d", int16(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 81 | fmt.Sprintf("%v", int16(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 82 | fmt.Sprint(int16(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 83 | fmt.Sprintf("%d", i32) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 84 | fmt.Sprintf("%v", i32) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 85 | fmt.Sprint(i32) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 86 | fmt.Sprintf("%d", int32(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 87 | fmt.Sprintf("%v", int32(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 88 | fmt.Sprint(int32(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 89 | fmt.Sprintf("%d", i64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 90 | fmt.Sprintf("%v", i64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 91 | fmt.Sprint(i64) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 92 | fmt.Sprintf("%d", int64(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 93 | fmt.Sprintf("%v", int64(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 94 | fmt.Sprint(int64(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 95 | 96 | var ui uint 97 | var ui8 uint8 98 | var ui16 uint16 99 | var ui32 uint32 100 | var ui64 uint64 101 | fmt.Sprintf("%d", ui) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 102 | fmt.Sprintf("%v", ui) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 103 | fmt.Sprint(ui) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 104 | fmt.Sprintf("%d", uint(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 105 | fmt.Sprintf("%v", uint(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 106 | fmt.Sprint(uint(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 107 | fmt.Sprintf("%d", ui8) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 108 | fmt.Sprintf("%v", ui8) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 109 | fmt.Sprint(ui8) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 110 | fmt.Sprintf("%d", uint8(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 111 | fmt.Sprintf("%v", uint8(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 112 | fmt.Sprint(uint8(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 113 | fmt.Sprintf("%d", ui16) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 114 | fmt.Sprintf("%v", ui16) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 115 | fmt.Sprint(ui16) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 116 | fmt.Sprintf("%d", uint16(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 117 | fmt.Sprintf("%v", uint16(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 118 | fmt.Sprint(uint16(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 119 | fmt.Sprintf("%d", ui32) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 120 | fmt.Sprintf("%v", ui32) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 121 | fmt.Sprint(ui32) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 122 | fmt.Sprintf("%d", uint32(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 123 | fmt.Sprintf("%v", uint32(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 124 | fmt.Sprint(uint32(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 125 | fmt.Sprintf("%d", ui64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 126 | fmt.Sprintf("%v", ui64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 127 | fmt.Sprintf("%x", ui64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 128 | fmt.Sprintf("%x", uint(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 129 | fmt.Sprint(ui64) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 130 | fmt.Sprintf("%d", uint64(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 131 | fmt.Sprintf("%v", uint64(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 132 | fmt.Sprint(uint64(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 133 | } 134 | 135 | func suggestedFixesTest() { 136 | _ = func() string { 137 | if false { 138 | return fmt.Sprint("replace me") 139 | } 140 | return fmt.Sprintf("%s", "replace me") 141 | } 142 | 143 | fmt.Println(fmt.Sprint(errSentinel)) 144 | fmt.Println(fmt.Sprintf("%s", errSentinel)) 145 | 146 | _ = func() string { 147 | switch 42 { 148 | case 1: 149 | return fmt.Sprint(false) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 150 | case 2: 151 | return fmt.Sprintf("%t", true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 152 | } 153 | return "" 154 | } 155 | 156 | var offset int 157 | params := url.Values{} 158 | params.Set("offset", fmt.Sprintf("%d", offset)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 159 | params.Set("offset", fmt.Sprint(offset)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 160 | 161 | var pubKey []byte 162 | if verifyPubKey := true; verifyPubKey { 163 | log.Println("pubkey=" + fmt.Sprintf("%x", pubKey)) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 164 | } 165 | 166 | var metaHash [16]byte 167 | fn := fmt.Sprintf("%s.%x", "coverage.MetaFilePref", metaHash) 168 | _ = "tmp." + fn + fmt.Sprintf("%d", time.Now().UnixNano()) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 169 | _ = "tmp." + fn + fmt.Sprint(time.Now().UnixNano()) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 170 | 171 | var change struct{ User struct{ ID uint } } 172 | var userStr string 173 | if id := change.User.ID; id != 0 { 174 | userStr = fmt.Sprintf("%d", id) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 175 | userStr = fmt.Sprint(id) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 176 | } 177 | _ = userStr 178 | } 179 | 180 | func negative() { 181 | const val = "val%d" 182 | 183 | _ = int32(42) 184 | 185 | fmt.Scan(42) 186 | fmt.Scanf("%d", 42) 187 | fmt.Println("%d", 42) 188 | fmt.Printf("%d") 189 | fmt.Printf("%v") 190 | fmt.Printf("%d", 42) 191 | fmt.Printf("%s %d", "hello", 42) 192 | fmt.Errorf("this is %s", "complex") 193 | 194 | fmt.Fprint(os.Stdout, "%d", 42) 195 | fmt.Fprintf(os.Stdout, "test") 196 | fmt.Fprintf(os.Stdout, "%d") 197 | fmt.Fprintf(os.Stdout, "%v") 198 | fmt.Fprintf(os.Stdout, "%d", 42) 199 | fmt.Fprintf(os.Stdout, "%s %d", "hello", 42) 200 | 201 | fmt.Sprint("test", 42) 202 | fmt.Sprint(42, 42) 203 | fmt.Sprintf("%d", 42, 42) 204 | fmt.Sprintf("%#d", 42) 205 | fmt.Sprintf("value %d", 42) 206 | fmt.Sprintf(val, 42) 207 | fmt.Sprintf("%s %v", "hello", "world") 208 | fmt.Sprintf("%#v", 42) 209 | fmt.Sprintf("%T", struct{ string }{}) 210 | fmt.Sprintf("%%v", 42) 211 | fmt.Sprintf("%3d", 42) 212 | fmt.Sprintf("% d", 42) 213 | fmt.Sprintf("%-10d", 42) 214 | fmt.Sprintf("%s %[1]s", "hello") 215 | fmt.Sprintf("%[1]s %[1]s", "hello") 216 | fmt.Sprintf("%[2]d %[1]d\n", 11, 22) 217 | fmt.Sprintf("%[3]*.[2]*[1]f", 12.0, 2, 6) 218 | fmt.Sprintf("%d %d %#[1]x %#x", 16, 17) 219 | 220 | // Integer. 221 | fmt.Sprintf("%#x", uint64(42)) 222 | fmt.Sprintf("%#v", uint64(42)) 223 | fmt.Sprintf("%#b", 42) 224 | fmt.Sprintf("%#o", 42) 225 | fmt.Sprintf("%#x", 42) 226 | fmt.Sprintf("%#X", 42) 227 | 228 | fmt.Sprintf("%b", 42) 229 | fmt.Sprintf("%c", 42) 230 | fmt.Sprintf("%o", 42) 231 | fmt.Sprintf("%O", 42) 232 | fmt.Sprintf("%q", 42) 233 | fmt.Sprintf("%x", 42) 234 | fmt.Sprintf("%X", 42) 235 | 236 | // Floating point. 237 | fmt.Sprintf("%9f", 42.42) 238 | fmt.Sprintf("%.2f", 42.42) 239 | fmt.Sprintf("%.2f", 42.42) 240 | fmt.Sprintf("%9.2f", 42.42) 241 | fmt.Sprintf("%9.f", 42.42) 242 | fmt.Sprintf("%.3g", 42.42) 243 | 244 | fmt.Sprintf("%b", float32(42.42)) 245 | fmt.Sprintf("%e", float32(42.42)) 246 | fmt.Sprintf("%E", float32(42.42)) 247 | fmt.Sprintf("%f", float32(42.42)) 248 | fmt.Sprintf("%F", float32(42.42)) 249 | fmt.Sprintf("%g", float32(42.42)) 250 | fmt.Sprintf("%G", float32(42.42)) 251 | fmt.Sprintf("%x", float32(42.42)) 252 | fmt.Sprintf("%X", float32(42.42)) 253 | fmt.Sprintf("%v", float32(42.42)) 254 | 255 | fmt.Sprintf("%b", 42.42) 256 | fmt.Sprintf("%e", 42.42) 257 | fmt.Sprintf("%E", 42.42) 258 | fmt.Sprintf("%f", 42.42) 259 | fmt.Sprintf("%F", 42.42) 260 | fmt.Sprintf("%g", 42.42) 261 | fmt.Sprintf("%G", 42.42) 262 | fmt.Sprintf("%x", 42.42) 263 | fmt.Sprintf("%X", 42.42) 264 | fmt.Sprintf("%v", 42.42) 265 | 266 | fmt.Sprintf("%b", 42i+42) 267 | fmt.Sprintf("%e", 42i+42) 268 | fmt.Sprintf("%E", 42i+42) 269 | fmt.Sprintf("%f", 42i+42) 270 | fmt.Sprintf("%F", 42i+42) 271 | fmt.Sprintf("%g", 42i+42) 272 | fmt.Sprintf("%G", 42i+42) 273 | fmt.Sprintf("%x", 42i+42) 274 | fmt.Sprintf("%X", 42i+42) 275 | fmt.Sprintf("%v", 42i+42) 276 | 277 | // String & slice of bytes. 278 | fmt.Sprintf("%q", "hello") 279 | fmt.Sprintf("%#q", `"hello"`) 280 | fmt.Sprintf("%+q", "hello") 281 | fmt.Sprintf("%X", "hello") 282 | 283 | // Slice. 284 | fmt.Sprintf("%x", []uint16{'d'}) 285 | fmt.Sprintf("%x", []uint32{'d'}) 286 | fmt.Sprintf("%x", []uint64{'d'}) 287 | fmt.Sprintf("%x", []uint{'d'}) 288 | fmt.Sprintf("%x", [1]byte{'c'}) 289 | fmt.Sprintf("%x", [1]uint8{'d'}) 290 | fmt.Sprintf("%x", [1]uint16{'d'}) 291 | fmt.Sprintf("%x", [1]uint32{'d'}) 292 | fmt.Sprintf("%x", [1]uint64{'d'}) 293 | fmt.Sprintf("%x", [1]uint{'d'}) 294 | fmt.Sprintf("%x", []int8{1}) 295 | fmt.Sprintf("%x", []int16{1}) 296 | fmt.Sprintf("%x", []int32{1}) 297 | fmt.Sprintf("%x", []int64{1}) 298 | fmt.Sprintf("%x", []int{1}) 299 | fmt.Sprintf("%x", [...]int8{1}) 300 | fmt.Sprintf("%x", [...]int16{1}) 301 | fmt.Sprintf("%x", [...]int32{1}) 302 | fmt.Sprintf("%x", [...]int64{1}) 303 | fmt.Sprintf("%x", [...]int{1}) 304 | fmt.Sprintf("%x", []string{"hello"}) 305 | fmt.Sprintf("%x", []rune{'a'}) 306 | 307 | fmt.Sprintf("% x", []byte{1, 2, 3}) 308 | fmt.Sprintf("% X", []byte{1, 2, 3}) 309 | fmt.Sprintf("%p", []byte{1, 2, 3}) 310 | fmt.Sprintf("%#p", []byte{1, 2, 3}) 311 | 312 | // Pointer. 313 | var ptr *int 314 | fmt.Sprintf("%v", ptr) 315 | fmt.Sprintf("%b", ptr) 316 | fmt.Sprintf("%d", ptr) 317 | fmt.Sprintf("%o", ptr) 318 | fmt.Sprintf("%x", ptr) 319 | fmt.Sprintf("%X", ptr) 320 | } 321 | 322 | func malformed() { 323 | fmt.Sprintf("%d", "example") 324 | fmt.Sprintf("%T", "example") 325 | fmt.Sprintf("%t", "example") 326 | fmt.Sprintf("%b", "example") 327 | fmt.Sprintf("%e", "example") 328 | fmt.Sprintf("%E", "example") 329 | fmt.Sprintf("%f", "example") 330 | fmt.Sprintf("%F", "example") 331 | fmt.Sprintf("%g", "example") 332 | fmt.Sprintf("%G", "example") 333 | fmt.Sprintf("%x", "example") 334 | fmt.Sprintf("%X", "example") 335 | 336 | fmt.Sprintf("%d", errSentinel) 337 | fmt.Sprintf("%T", errSentinel) 338 | fmt.Sprintf("%t", errSentinel) 339 | fmt.Sprintf("%b", errSentinel) 340 | fmt.Sprintf("%e", errSentinel) 341 | fmt.Sprintf("%E", errSentinel) 342 | fmt.Sprintf("%f", errSentinel) 343 | fmt.Sprintf("%F", errSentinel) 344 | fmt.Sprintf("%g", errSentinel) 345 | fmt.Sprintf("%G", errSentinel) 346 | fmt.Sprintf("%x", errSentinel) 347 | fmt.Sprintf("%X", errSentinel) 348 | 349 | fmt.Sprintf("%d", true) 350 | fmt.Sprintf("%T", true) 351 | fmt.Sprintf("%b", true) 352 | fmt.Sprintf("%e", true) 353 | fmt.Sprintf("%E", true) 354 | fmt.Sprintf("%f", true) 355 | fmt.Sprintf("%F", true) 356 | fmt.Sprintf("%g", true) 357 | fmt.Sprintf("%G", true) 358 | fmt.Sprintf("%x", true) 359 | fmt.Sprintf("%X", true) 360 | 361 | var bb []byte 362 | fmt.Sprintf("%d", bb) 363 | fmt.Sprintf("%T", bb) 364 | fmt.Sprintf("%t", bb) 365 | fmt.Sprintf("%b", bb) 366 | fmt.Sprintf("%e", bb) 367 | fmt.Sprintf("%E", bb) 368 | fmt.Sprintf("%f", bb) 369 | fmt.Sprintf("%F", bb) 370 | fmt.Sprintf("%g", bb) 371 | fmt.Sprintf("%G", bb) 372 | fmt.Sprintf("%X", bb) 373 | fmt.Sprintf("%v", bb) 374 | 375 | fmt.Sprintf("%T", 42) 376 | fmt.Sprintf("%t", 42) 377 | fmt.Sprintf("%b", 42) 378 | fmt.Sprintf("%e", 42) 379 | fmt.Sprintf("%E", 42) 380 | fmt.Sprintf("%f", 42) 381 | fmt.Sprintf("%F", 42) 382 | fmt.Sprintf("%g", 42) 383 | fmt.Sprintf("%G", 42) 384 | fmt.Sprintf("%x", 42) 385 | fmt.Sprintf("%X", 42) 386 | 387 | fmt.Sprintf("%T", uint(42)) 388 | fmt.Sprintf("%t", uint(42)) 389 | fmt.Sprintf("%b", uint(42)) 390 | fmt.Sprintf("%e", uint(42)) 391 | fmt.Sprintf("%E", uint(42)) 392 | fmt.Sprintf("%f", uint(42)) 393 | fmt.Sprintf("%F", uint(42)) 394 | fmt.Sprintf("%g", uint(42)) 395 | fmt.Sprintf("%G", uint(42)) 396 | fmt.Sprintf("%X", uint(42)) 397 | 398 | fmt.Sprintf("%d", 42.42) 399 | fmt.Sprintf("%d", map[string]string{}) 400 | fmt.Sprint(make(chan int)) 401 | fmt.Sprint([]int{1, 2, 3}) 402 | } 403 | -------------------------------------------------------------------------------- /analyzer/testdata/src/without-bool-format/p.go: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | import ( // want "Fix imports" 4 | "errors" 5 | "fmt" 6 | "io" 7 | "log" 8 | "net/url" 9 | "os" 10 | "time" 11 | ) 12 | 13 | var errSentinel = errors.New("connection refused") 14 | 15 | func positive() { 16 | var s string 17 | fmt.Sprintf("%s", "hello") // want "string-format: fmt.Sprintf can be replaced with just using the string" 18 | fmt.Sprintf("%v", "hello") // want "string-format: fmt.Sprintf can be replaced with just using the string" 19 | fmt.Sprintf("hello") // want "string-format: fmt.Sprintf can be replaced with just using the string" 20 | fmt.Sprint("hello") // want "string-format: fmt.Sprint can be replaced with just using the string" 21 | fmt.Sprintf("%s", s) // want "string-format: fmt.Sprintf can be replaced with just using the string" 22 | fmt.Sprintf("%[1]s", s) // want "string-format: fmt.Sprintf can be replaced with just using the string" 23 | fmt.Sprintf("%v", s) // want "string-format: fmt.Sprintf can be replaced with just using the string" 24 | fmt.Sprint(s) // want "string-format: fmt.Sprint can be replaced with just using the string" 25 | fmt.Errorf("hello") // want "error-format: fmt.Errorf can be replaced with errors.New" 26 | 27 | fmt.Sprintf("Hello %s", s) // want "string-format: fmt.Sprintf can be replaced with string concatenation" 28 | fmt.Sprintf("%s says Hello", s) // want "string-format: fmt.Sprintf can be replaced with string concatenation" 29 | fmt.Sprintf("Hello says %[1]s", s) // want "string-format: fmt.Sprintf can be replaced with string concatenation" 30 | 31 | var err error 32 | fmt.Sprintf("%s", errSentinel) 33 | fmt.Sprintf("%v", errSentinel) 34 | fmt.Sprint(errSentinel) 35 | fmt.Sprintf("%s", io.EOF) 36 | fmt.Sprintf("%v", io.EOF) 37 | fmt.Sprint(io.EOF) 38 | fmt.Sprintf("%s", err) 39 | fmt.Sprintf("%v", err) 40 | fmt.Sprint(err) 41 | 42 | var b bool 43 | fmt.Sprintf("%t", true) 44 | fmt.Sprintf("%v", true) 45 | fmt.Sprint(true) 46 | fmt.Sprintf("%t", false) 47 | fmt.Sprintf("%v", false) 48 | fmt.Sprint(false) 49 | fmt.Sprintf("%t", b) 50 | fmt.Sprintf("%v", b) 51 | fmt.Sprint(b) 52 | 53 | var bs []byte 54 | var ba [3]byte 55 | fmt.Sprintf("%x", []byte{'a'}) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 56 | fmt.Sprintf("%x", []uint8{'b'}) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 57 | fmt.Sprintf("%x", bs) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 58 | fmt.Sprintf("%x", ba) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 59 | 60 | var i int 61 | var i8 int8 62 | var i16 int16 63 | var i32 int32 64 | var i64 int64 65 | fmt.Sprintf("%d", i) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 66 | fmt.Sprintf("%v", i) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 67 | fmt.Sprint(i) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 68 | fmt.Sprintf("%d", 42) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 69 | fmt.Sprintf("%v", 42) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 70 | fmt.Sprint(42) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 71 | fmt.Sprintf("%d", i8) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 72 | fmt.Sprintf("%v", i8) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 73 | fmt.Sprint(i8) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 74 | fmt.Sprintf("%d", int8(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 75 | fmt.Sprintf("%v", int8(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 76 | fmt.Sprint(int8(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 77 | fmt.Sprintf("%d", i16) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 78 | fmt.Sprintf("%v", i16) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 79 | fmt.Sprint(i16) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 80 | fmt.Sprintf("%d", int16(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 81 | fmt.Sprintf("%v", int16(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 82 | fmt.Sprint(int16(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 83 | fmt.Sprintf("%d", i32) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 84 | fmt.Sprintf("%v", i32) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 85 | fmt.Sprint(i32) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 86 | fmt.Sprintf("%d", int32(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 87 | fmt.Sprintf("%v", int32(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 88 | fmt.Sprint(int32(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 89 | fmt.Sprintf("%d", i64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 90 | fmt.Sprintf("%v", i64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 91 | fmt.Sprint(i64) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 92 | fmt.Sprintf("%d", int64(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 93 | fmt.Sprintf("%v", int64(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 94 | fmt.Sprint(int64(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 95 | 96 | var ui uint 97 | var ui8 uint8 98 | var ui16 uint16 99 | var ui32 uint32 100 | var ui64 uint64 101 | fmt.Sprintf("%d", ui) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 102 | fmt.Sprintf("%v", ui) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 103 | fmt.Sprint(ui) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 104 | fmt.Sprintf("%d", uint(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 105 | fmt.Sprintf("%v", uint(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 106 | fmt.Sprint(uint(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 107 | fmt.Sprintf("%d", ui8) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 108 | fmt.Sprintf("%v", ui8) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 109 | fmt.Sprint(ui8) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 110 | fmt.Sprintf("%d", uint8(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 111 | fmt.Sprintf("%v", uint8(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 112 | fmt.Sprint(uint8(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 113 | fmt.Sprintf("%d", ui16) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 114 | fmt.Sprintf("%v", ui16) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 115 | fmt.Sprint(ui16) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 116 | fmt.Sprintf("%d", uint16(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 117 | fmt.Sprintf("%v", uint16(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 118 | fmt.Sprint(uint16(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 119 | fmt.Sprintf("%d", ui32) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 120 | fmt.Sprintf("%v", ui32) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 121 | fmt.Sprint(ui32) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 122 | fmt.Sprintf("%d", uint32(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 123 | fmt.Sprintf("%v", uint32(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 124 | fmt.Sprint(uint32(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 125 | fmt.Sprintf("%d", ui64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 126 | fmt.Sprintf("%v", ui64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 127 | fmt.Sprintf("%x", ui64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 128 | fmt.Sprintf("%x", uint(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 129 | fmt.Sprint(ui64) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 130 | fmt.Sprintf("%d", uint64(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 131 | fmt.Sprintf("%v", uint64(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 132 | fmt.Sprint(uint64(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 133 | } 134 | 135 | func suggestedFixesTest() { 136 | _ = func() string { 137 | if false { 138 | return fmt.Sprint("replace me") // want "string-format: fmt.Sprint can be replaced with just using the string" 139 | } 140 | return fmt.Sprintf("%s", "replace me") // want "string-format: fmt.Sprintf can be replaced with just using the string" 141 | } 142 | 143 | fmt.Println(fmt.Sprint(errSentinel)) 144 | fmt.Println(fmt.Sprintf("%s", errSentinel)) 145 | 146 | _ = func() string { 147 | switch 42 { 148 | case 1: 149 | return fmt.Sprint(false) 150 | case 2: 151 | return fmt.Sprintf("%t", true) 152 | } 153 | return "" 154 | } 155 | 156 | var offset int 157 | params := url.Values{} 158 | params.Set("offset", fmt.Sprintf("%d", offset)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 159 | params.Set("offset", fmt.Sprint(offset)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 160 | 161 | var pubKey []byte 162 | if verifyPubKey := true; verifyPubKey { 163 | log.Println("pubkey=" + fmt.Sprintf("%x", pubKey)) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 164 | } 165 | 166 | var metaHash [16]byte 167 | fn := fmt.Sprintf("%s.%x", "coverage.MetaFilePref", metaHash) 168 | _ = "tmp." + fn + fmt.Sprintf("%d", time.Now().UnixNano()) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 169 | _ = "tmp." + fn + fmt.Sprint(time.Now().UnixNano()) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 170 | 171 | var change struct{ User struct{ ID uint } } 172 | var userStr string 173 | if id := change.User.ID; id != 0 { 174 | userStr = fmt.Sprintf("%d", id) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 175 | userStr = fmt.Sprint(id) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 176 | } 177 | _ = userStr 178 | } 179 | 180 | func negative() { 181 | const val = "val%d" 182 | 183 | _ = int32(42) 184 | 185 | fmt.Scan(42) 186 | fmt.Scanf("%d", 42) 187 | fmt.Println("%d", 42) 188 | fmt.Printf("%d") 189 | fmt.Printf("%v") 190 | fmt.Printf("%d", 42) 191 | fmt.Printf("%s %d", "hello", 42) 192 | fmt.Errorf("this is %s", "complex") 193 | 194 | fmt.Fprint(os.Stdout, "%d", 42) 195 | fmt.Fprintf(os.Stdout, "test") 196 | fmt.Fprintf(os.Stdout, "%d") 197 | fmt.Fprintf(os.Stdout, "%v") 198 | fmt.Fprintf(os.Stdout, "%d", 42) 199 | fmt.Fprintf(os.Stdout, "%s %d", "hello", 42) 200 | 201 | fmt.Sprint("test", 42) 202 | fmt.Sprint(42, 42) 203 | fmt.Sprintf("%d", 42, 42) 204 | fmt.Sprintf("%#d", 42) 205 | fmt.Sprintf("value %d", 42) 206 | fmt.Sprintf(val, 42) 207 | fmt.Sprintf("%s %v", "hello", "world") 208 | fmt.Sprintf("%#v", 42) 209 | fmt.Sprintf("%T", struct{ string }{}) 210 | fmt.Sprintf("%%v", 42) 211 | fmt.Sprintf("%3d", 42) 212 | fmt.Sprintf("% d", 42) 213 | fmt.Sprintf("%-10d", 42) 214 | fmt.Sprintf("%s %[1]s", "hello") 215 | fmt.Sprintf("%[1]s %[1]s", "hello") 216 | fmt.Sprintf("%[2]d %[1]d\n", 11, 22) 217 | fmt.Sprintf("%[3]*.[2]*[1]f", 12.0, 2, 6) 218 | fmt.Sprintf("%d %d %#[1]x %#x", 16, 17) 219 | 220 | // Integer. 221 | fmt.Sprintf("%#x", uint64(42)) 222 | fmt.Sprintf("%#v", uint64(42)) 223 | fmt.Sprintf("%#b", 42) 224 | fmt.Sprintf("%#o", 42) 225 | fmt.Sprintf("%#x", 42) 226 | fmt.Sprintf("%#X", 42) 227 | 228 | fmt.Sprintf("%b", 42) 229 | fmt.Sprintf("%c", 42) 230 | fmt.Sprintf("%o", 42) 231 | fmt.Sprintf("%O", 42) 232 | fmt.Sprintf("%q", 42) 233 | fmt.Sprintf("%x", 42) 234 | fmt.Sprintf("%X", 42) 235 | 236 | // Floating point. 237 | fmt.Sprintf("%9f", 42.42) 238 | fmt.Sprintf("%.2f", 42.42) 239 | fmt.Sprintf("%.2f", 42.42) 240 | fmt.Sprintf("%9.2f", 42.42) 241 | fmt.Sprintf("%9.f", 42.42) 242 | fmt.Sprintf("%.3g", 42.42) 243 | 244 | fmt.Sprintf("%b", float32(42.42)) 245 | fmt.Sprintf("%e", float32(42.42)) 246 | fmt.Sprintf("%E", float32(42.42)) 247 | fmt.Sprintf("%f", float32(42.42)) 248 | fmt.Sprintf("%F", float32(42.42)) 249 | fmt.Sprintf("%g", float32(42.42)) 250 | fmt.Sprintf("%G", float32(42.42)) 251 | fmt.Sprintf("%x", float32(42.42)) 252 | fmt.Sprintf("%X", float32(42.42)) 253 | fmt.Sprintf("%v", float32(42.42)) 254 | 255 | fmt.Sprintf("%b", 42.42) 256 | fmt.Sprintf("%e", 42.42) 257 | fmt.Sprintf("%E", 42.42) 258 | fmt.Sprintf("%f", 42.42) 259 | fmt.Sprintf("%F", 42.42) 260 | fmt.Sprintf("%g", 42.42) 261 | fmt.Sprintf("%G", 42.42) 262 | fmt.Sprintf("%x", 42.42) 263 | fmt.Sprintf("%X", 42.42) 264 | fmt.Sprintf("%v", 42.42) 265 | 266 | fmt.Sprintf("%b", 42i+42) 267 | fmt.Sprintf("%e", 42i+42) 268 | fmt.Sprintf("%E", 42i+42) 269 | fmt.Sprintf("%f", 42i+42) 270 | fmt.Sprintf("%F", 42i+42) 271 | fmt.Sprintf("%g", 42i+42) 272 | fmt.Sprintf("%G", 42i+42) 273 | fmt.Sprintf("%x", 42i+42) 274 | fmt.Sprintf("%X", 42i+42) 275 | fmt.Sprintf("%v", 42i+42) 276 | 277 | // String & slice of bytes. 278 | fmt.Sprintf("%q", "hello") 279 | fmt.Sprintf("%#q", `"hello"`) 280 | fmt.Sprintf("%+q", "hello") 281 | fmt.Sprintf("%X", "hello") 282 | 283 | // Slice. 284 | fmt.Sprintf("%x", []uint16{'d'}) 285 | fmt.Sprintf("%x", []uint32{'d'}) 286 | fmt.Sprintf("%x", []uint64{'d'}) 287 | fmt.Sprintf("%x", []uint{'d'}) 288 | fmt.Sprintf("%x", [1]byte{'c'}) 289 | fmt.Sprintf("%x", [1]uint8{'d'}) 290 | fmt.Sprintf("%x", [1]uint16{'d'}) 291 | fmt.Sprintf("%x", [1]uint32{'d'}) 292 | fmt.Sprintf("%x", [1]uint64{'d'}) 293 | fmt.Sprintf("%x", [1]uint{'d'}) 294 | fmt.Sprintf("%x", []int8{1}) 295 | fmt.Sprintf("%x", []int16{1}) 296 | fmt.Sprintf("%x", []int32{1}) 297 | fmt.Sprintf("%x", []int64{1}) 298 | fmt.Sprintf("%x", []int{1}) 299 | fmt.Sprintf("%x", [...]int8{1}) 300 | fmt.Sprintf("%x", [...]int16{1}) 301 | fmt.Sprintf("%x", [...]int32{1}) 302 | fmt.Sprintf("%x", [...]int64{1}) 303 | fmt.Sprintf("%x", [...]int{1}) 304 | fmt.Sprintf("%x", []string{"hello"}) 305 | fmt.Sprintf("%x", []rune{'a'}) 306 | 307 | fmt.Sprintf("% x", []byte{1, 2, 3}) 308 | fmt.Sprintf("% X", []byte{1, 2, 3}) 309 | fmt.Sprintf("%p", []byte{1, 2, 3}) 310 | fmt.Sprintf("%#p", []byte{1, 2, 3}) 311 | 312 | // Pointer. 313 | var ptr *int 314 | fmt.Sprintf("%v", ptr) 315 | fmt.Sprintf("%b", ptr) 316 | fmt.Sprintf("%d", ptr) 317 | fmt.Sprintf("%o", ptr) 318 | fmt.Sprintf("%x", ptr) 319 | fmt.Sprintf("%X", ptr) 320 | } 321 | 322 | func malformed() { 323 | fmt.Sprintf("%d", "example") 324 | fmt.Sprintf("%T", "example") 325 | fmt.Sprintf("%t", "example") 326 | fmt.Sprintf("%b", "example") 327 | fmt.Sprintf("%e", "example") 328 | fmt.Sprintf("%E", "example") 329 | fmt.Sprintf("%f", "example") 330 | fmt.Sprintf("%F", "example") 331 | fmt.Sprintf("%g", "example") 332 | fmt.Sprintf("%G", "example") 333 | fmt.Sprintf("%x", "example") 334 | fmt.Sprintf("%X", "example") 335 | 336 | fmt.Sprintf("%d", errSentinel) 337 | fmt.Sprintf("%T", errSentinel) 338 | fmt.Sprintf("%t", errSentinel) 339 | fmt.Sprintf("%b", errSentinel) 340 | fmt.Sprintf("%e", errSentinel) 341 | fmt.Sprintf("%E", errSentinel) 342 | fmt.Sprintf("%f", errSentinel) 343 | fmt.Sprintf("%F", errSentinel) 344 | fmt.Sprintf("%g", errSentinel) 345 | fmt.Sprintf("%G", errSentinel) 346 | fmt.Sprintf("%x", errSentinel) 347 | fmt.Sprintf("%X", errSentinel) 348 | 349 | fmt.Sprintf("%d", true) 350 | fmt.Sprintf("%T", true) 351 | fmt.Sprintf("%b", true) 352 | fmt.Sprintf("%e", true) 353 | fmt.Sprintf("%E", true) 354 | fmt.Sprintf("%f", true) 355 | fmt.Sprintf("%F", true) 356 | fmt.Sprintf("%g", true) 357 | fmt.Sprintf("%G", true) 358 | fmt.Sprintf("%x", true) 359 | fmt.Sprintf("%X", true) 360 | 361 | var bb []byte 362 | fmt.Sprintf("%d", bb) 363 | fmt.Sprintf("%T", bb) 364 | fmt.Sprintf("%t", bb) 365 | fmt.Sprintf("%b", bb) 366 | fmt.Sprintf("%e", bb) 367 | fmt.Sprintf("%E", bb) 368 | fmt.Sprintf("%f", bb) 369 | fmt.Sprintf("%F", bb) 370 | fmt.Sprintf("%g", bb) 371 | fmt.Sprintf("%G", bb) 372 | fmt.Sprintf("%X", bb) 373 | fmt.Sprintf("%v", bb) 374 | 375 | fmt.Sprintf("%T", 42) 376 | fmt.Sprintf("%t", 42) 377 | fmt.Sprintf("%b", 42) 378 | fmt.Sprintf("%e", 42) 379 | fmt.Sprintf("%E", 42) 380 | fmt.Sprintf("%f", 42) 381 | fmt.Sprintf("%F", 42) 382 | fmt.Sprintf("%g", 42) 383 | fmt.Sprintf("%G", 42) 384 | fmt.Sprintf("%x", 42) 385 | fmt.Sprintf("%X", 42) 386 | 387 | fmt.Sprintf("%T", uint(42)) 388 | fmt.Sprintf("%t", uint(42)) 389 | fmt.Sprintf("%b", uint(42)) 390 | fmt.Sprintf("%e", uint(42)) 391 | fmt.Sprintf("%E", uint(42)) 392 | fmt.Sprintf("%f", uint(42)) 393 | fmt.Sprintf("%F", uint(42)) 394 | fmt.Sprintf("%g", uint(42)) 395 | fmt.Sprintf("%G", uint(42)) 396 | fmt.Sprintf("%X", uint(42)) 397 | 398 | fmt.Sprintf("%d", 42.42) 399 | fmt.Sprintf("%d", map[string]string{}) 400 | fmt.Sprint(make(chan int)) 401 | fmt.Sprint([]int{1, 2, 3}) 402 | } 403 | -------------------------------------------------------------------------------- /analyzer/testdata/src/without-bool-format/p.go.golden: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | import ( // want "Fix imports" 4 | "encoding/hex" 5 | "errors" 6 | "fmt" 7 | "io" 8 | "log" 9 | "net/url" 10 | "os" 11 | "strconv" 12 | "time" 13 | ) 14 | 15 | var errSentinel = errors.New("connection refused") 16 | 17 | func positive() { 18 | var s string 19 | "hello" // want "string-format: fmt.Sprintf can be replaced with just using the string" 20 | "hello" // want "string-format: fmt.Sprintf can be replaced with just using the string" 21 | "hello" // want "string-format: fmt.Sprintf can be replaced with just using the string" 22 | "hello" // want "string-format: fmt.Sprint can be replaced with just using the string" 23 | s // want "string-format: fmt.Sprintf can be replaced with just using the string" 24 | s // want "string-format: fmt.Sprintf can be replaced with just using the string" 25 | s // want "string-format: fmt.Sprintf can be replaced with just using the string" 26 | s // want "string-format: fmt.Sprint can be replaced with just using the string" 27 | errors.New("hello") // want "error-format: fmt.Errorf can be replaced with errors.New" 28 | 29 | "Hello " + s // want "string-format: fmt.Sprintf can be replaced with string concatenation" 30 | s + " says Hello" // want "string-format: fmt.Sprintf can be replaced with string concatenation" 31 | "Hello says " + s // want "string-format: fmt.Sprintf can be replaced with string concatenation" 32 | 33 | var err error 34 | fmt.Sprintf("%s", errSentinel) 35 | fmt.Sprintf("%v", errSentinel) 36 | fmt.Sprint(errSentinel) 37 | fmt.Sprintf("%s", io.EOF) 38 | fmt.Sprintf("%v", io.EOF) 39 | fmt.Sprint(io.EOF) 40 | fmt.Sprintf("%s", err) 41 | fmt.Sprintf("%v", err) 42 | fmt.Sprint(err) 43 | 44 | var b bool 45 | fmt.Sprintf("%t", true) 46 | fmt.Sprintf("%v", true) 47 | fmt.Sprint(true) 48 | fmt.Sprintf("%t", false) 49 | fmt.Sprintf("%v", false) 50 | fmt.Sprint(false) 51 | fmt.Sprintf("%t", b) 52 | fmt.Sprintf("%v", b) 53 | fmt.Sprint(b) 54 | 55 | var bs []byte 56 | var ba [3]byte 57 | hex.EncodeToString([]byte{'a'}) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 58 | hex.EncodeToString([]uint8{'b'}) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 59 | hex.EncodeToString(bs) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 60 | hex.EncodeToString(ba[:]) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 61 | 62 | var i int 63 | var i8 int8 64 | var i16 int16 65 | var i32 int32 66 | var i64 int64 67 | strconv.Itoa(i) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 68 | strconv.Itoa(i) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 69 | strconv.Itoa(i) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 70 | strconv.Itoa(42) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 71 | strconv.Itoa(42) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 72 | strconv.Itoa(42) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 73 | strconv.Itoa(int(i8)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 74 | strconv.Itoa(int(i8)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 75 | strconv.Itoa(int(i8)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 76 | strconv.Itoa(int(int8(42))) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 77 | strconv.Itoa(int(int8(42))) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 78 | strconv.Itoa(int(int8(42))) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 79 | strconv.Itoa(int(i16)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 80 | strconv.Itoa(int(i16)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 81 | strconv.Itoa(int(i16)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 82 | strconv.Itoa(int(int16(42))) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 83 | strconv.Itoa(int(int16(42))) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 84 | strconv.Itoa(int(int16(42))) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 85 | strconv.Itoa(int(i32)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 86 | strconv.Itoa(int(i32)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 87 | strconv.Itoa(int(i32)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 88 | strconv.Itoa(int(int32(42))) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 89 | strconv.Itoa(int(int32(42))) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 90 | strconv.Itoa(int(int32(42))) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 91 | strconv.FormatInt(i64, 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 92 | strconv.FormatInt(i64, 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 93 | strconv.FormatInt(i64, 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 94 | strconv.FormatInt(int64(42), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 95 | strconv.FormatInt(int64(42), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 96 | strconv.FormatInt(int64(42), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 97 | 98 | var ui uint 99 | var ui8 uint8 100 | var ui16 uint16 101 | var ui32 uint32 102 | var ui64 uint64 103 | strconv.FormatUint(uint64(ui), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 104 | strconv.FormatUint(uint64(ui), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 105 | strconv.FormatUint(uint64(ui), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 106 | strconv.FormatUint(uint64(uint(42)), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 107 | strconv.FormatUint(uint64(uint(42)), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 108 | strconv.FormatUint(uint64(uint(42)), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 109 | strconv.FormatUint(uint64(ui8), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 110 | strconv.FormatUint(uint64(ui8), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 111 | strconv.FormatUint(uint64(ui8), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 112 | strconv.FormatUint(uint64(uint8(42)), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 113 | strconv.FormatUint(uint64(uint8(42)), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 114 | strconv.FormatUint(uint64(uint8(42)), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 115 | strconv.FormatUint(uint64(ui16), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 116 | strconv.FormatUint(uint64(ui16), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 117 | strconv.FormatUint(uint64(ui16), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 118 | strconv.FormatUint(uint64(uint16(42)), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 119 | strconv.FormatUint(uint64(uint16(42)), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 120 | strconv.FormatUint(uint64(uint16(42)), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 121 | strconv.FormatUint(uint64(ui32), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 122 | strconv.FormatUint(uint64(ui32), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 123 | strconv.FormatUint(uint64(ui32), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 124 | strconv.FormatUint(uint64(uint32(42)), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 125 | strconv.FormatUint(uint64(uint32(42)), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 126 | strconv.FormatUint(uint64(uint32(42)), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 127 | strconv.FormatUint(ui64, 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 128 | strconv.FormatUint(ui64, 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 129 | strconv.FormatUint(ui64, 16) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 130 | strconv.FormatUint(uint64(uint(42)), 16) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 131 | strconv.FormatUint(ui64, 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 132 | strconv.FormatUint(uint64(42), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 133 | strconv.FormatUint(uint64(42), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 134 | strconv.FormatUint(uint64(42), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 135 | } 136 | 137 | func suggestedFixesTest() { 138 | _ = func() string { 139 | if false { 140 | return "replace me" // want "string-format: fmt.Sprint can be replaced with just using the string" 141 | } 142 | return "replace me" // want "string-format: fmt.Sprintf can be replaced with just using the string" 143 | } 144 | 145 | fmt.Println(fmt.Sprint(errSentinel)) 146 | fmt.Println(fmt.Sprintf("%s", errSentinel)) 147 | 148 | _ = func() string { 149 | switch 42 { 150 | case 1: 151 | return fmt.Sprint(false) 152 | case 2: 153 | return fmt.Sprintf("%t", true) 154 | } 155 | return "" 156 | } 157 | 158 | var offset int 159 | params := url.Values{} 160 | params.Set("offset", strconv.Itoa(offset)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 161 | params.Set("offset", strconv.Itoa(offset)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 162 | 163 | var pubKey []byte 164 | if verifyPubKey := true; verifyPubKey { 165 | log.Println("pubkey=" + hex.EncodeToString(pubKey)) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 166 | } 167 | 168 | var metaHash [16]byte 169 | fn := fmt.Sprintf("%s.%x", "coverage.MetaFilePref", metaHash) 170 | _ = "tmp." + fn + strconv.FormatInt(time.Now().UnixNano(), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 171 | _ = "tmp." + fn + strconv.FormatInt(time.Now().UnixNano(), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 172 | 173 | var change struct{ User struct{ ID uint } } 174 | var userStr string 175 | if id := change.User.ID; id != 0 { 176 | userStr = strconv.FormatUint(uint64(id), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 177 | userStr = strconv.FormatUint(uint64(id), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 178 | } 179 | _ = userStr 180 | } 181 | 182 | func negative() { 183 | const val = "val%d" 184 | 185 | _ = int32(42) 186 | 187 | fmt.Scan(42) 188 | fmt.Scanf("%d", 42) 189 | fmt.Println("%d", 42) 190 | fmt.Printf("%d") 191 | fmt.Printf("%v") 192 | fmt.Printf("%d", 42) 193 | fmt.Printf("%s %d", "hello", 42) 194 | fmt.Errorf("this is %s", "complex") 195 | 196 | fmt.Fprint(os.Stdout, "%d", 42) 197 | fmt.Fprintf(os.Stdout, "test") 198 | fmt.Fprintf(os.Stdout, "%d") 199 | fmt.Fprintf(os.Stdout, "%v") 200 | fmt.Fprintf(os.Stdout, "%d", 42) 201 | fmt.Fprintf(os.Stdout, "%s %d", "hello", 42) 202 | 203 | fmt.Sprint("test", 42) 204 | fmt.Sprint(42, 42) 205 | fmt.Sprintf("%d", 42, 42) 206 | fmt.Sprintf("%#d", 42) 207 | fmt.Sprintf("value %d", 42) 208 | fmt.Sprintf(val, 42) 209 | fmt.Sprintf("%s %v", "hello", "world") 210 | fmt.Sprintf("%#v", 42) 211 | fmt.Sprintf("%T", struct{ string }{}) 212 | fmt.Sprintf("%%v", 42) 213 | fmt.Sprintf("%3d", 42) 214 | fmt.Sprintf("% d", 42) 215 | fmt.Sprintf("%-10d", 42) 216 | fmt.Sprintf("%s %[1]s", "hello") 217 | fmt.Sprintf("%[1]s %[1]s", "hello") 218 | fmt.Sprintf("%[2]d %[1]d\n", 11, 22) 219 | fmt.Sprintf("%[3]*.[2]*[1]f", 12.0, 2, 6) 220 | fmt.Sprintf("%d %d %#[1]x %#x", 16, 17) 221 | 222 | // Integer. 223 | fmt.Sprintf("%#x", uint64(42)) 224 | fmt.Sprintf("%#v", uint64(42)) 225 | fmt.Sprintf("%#b", 42) 226 | fmt.Sprintf("%#o", 42) 227 | fmt.Sprintf("%#x", 42) 228 | fmt.Sprintf("%#X", 42) 229 | 230 | fmt.Sprintf("%b", 42) 231 | fmt.Sprintf("%c", 42) 232 | fmt.Sprintf("%o", 42) 233 | fmt.Sprintf("%O", 42) 234 | fmt.Sprintf("%q", 42) 235 | fmt.Sprintf("%x", 42) 236 | fmt.Sprintf("%X", 42) 237 | 238 | // Floating point. 239 | fmt.Sprintf("%9f", 42.42) 240 | fmt.Sprintf("%.2f", 42.42) 241 | fmt.Sprintf("%.2f", 42.42) 242 | fmt.Sprintf("%9.2f", 42.42) 243 | fmt.Sprintf("%9.f", 42.42) 244 | fmt.Sprintf("%.3g", 42.42) 245 | 246 | fmt.Sprintf("%b", float32(42.42)) 247 | fmt.Sprintf("%e", float32(42.42)) 248 | fmt.Sprintf("%E", float32(42.42)) 249 | fmt.Sprintf("%f", float32(42.42)) 250 | fmt.Sprintf("%F", float32(42.42)) 251 | fmt.Sprintf("%g", float32(42.42)) 252 | fmt.Sprintf("%G", float32(42.42)) 253 | fmt.Sprintf("%x", float32(42.42)) 254 | fmt.Sprintf("%X", float32(42.42)) 255 | fmt.Sprintf("%v", float32(42.42)) 256 | 257 | fmt.Sprintf("%b", 42.42) 258 | fmt.Sprintf("%e", 42.42) 259 | fmt.Sprintf("%E", 42.42) 260 | fmt.Sprintf("%f", 42.42) 261 | fmt.Sprintf("%F", 42.42) 262 | fmt.Sprintf("%g", 42.42) 263 | fmt.Sprintf("%G", 42.42) 264 | fmt.Sprintf("%x", 42.42) 265 | fmt.Sprintf("%X", 42.42) 266 | fmt.Sprintf("%v", 42.42) 267 | 268 | fmt.Sprintf("%b", 42i+42) 269 | fmt.Sprintf("%e", 42i+42) 270 | fmt.Sprintf("%E", 42i+42) 271 | fmt.Sprintf("%f", 42i+42) 272 | fmt.Sprintf("%F", 42i+42) 273 | fmt.Sprintf("%g", 42i+42) 274 | fmt.Sprintf("%G", 42i+42) 275 | fmt.Sprintf("%x", 42i+42) 276 | fmt.Sprintf("%X", 42i+42) 277 | fmt.Sprintf("%v", 42i+42) 278 | 279 | // String & slice of bytes. 280 | fmt.Sprintf("%q", "hello") 281 | fmt.Sprintf("%#q", `"hello"`) 282 | fmt.Sprintf("%+q", "hello") 283 | fmt.Sprintf("%X", "hello") 284 | 285 | // Slice. 286 | fmt.Sprintf("%x", []uint16{'d'}) 287 | fmt.Sprintf("%x", []uint32{'d'}) 288 | fmt.Sprintf("%x", []uint64{'d'}) 289 | fmt.Sprintf("%x", []uint{'d'}) 290 | fmt.Sprintf("%x", [1]byte{'c'}) 291 | fmt.Sprintf("%x", [1]uint8{'d'}) 292 | fmt.Sprintf("%x", [1]uint16{'d'}) 293 | fmt.Sprintf("%x", [1]uint32{'d'}) 294 | fmt.Sprintf("%x", [1]uint64{'d'}) 295 | fmt.Sprintf("%x", [1]uint{'d'}) 296 | fmt.Sprintf("%x", []int8{1}) 297 | fmt.Sprintf("%x", []int16{1}) 298 | fmt.Sprintf("%x", []int32{1}) 299 | fmt.Sprintf("%x", []int64{1}) 300 | fmt.Sprintf("%x", []int{1}) 301 | fmt.Sprintf("%x", [...]int8{1}) 302 | fmt.Sprintf("%x", [...]int16{1}) 303 | fmt.Sprintf("%x", [...]int32{1}) 304 | fmt.Sprintf("%x", [...]int64{1}) 305 | fmt.Sprintf("%x", [...]int{1}) 306 | fmt.Sprintf("%x", []string{"hello"}) 307 | fmt.Sprintf("%x", []rune{'a'}) 308 | 309 | fmt.Sprintf("% x", []byte{1, 2, 3}) 310 | fmt.Sprintf("% X", []byte{1, 2, 3}) 311 | fmt.Sprintf("%p", []byte{1, 2, 3}) 312 | fmt.Sprintf("%#p", []byte{1, 2, 3}) 313 | 314 | // Pointer. 315 | var ptr *int 316 | fmt.Sprintf("%v", ptr) 317 | fmt.Sprintf("%b", ptr) 318 | fmt.Sprintf("%d", ptr) 319 | fmt.Sprintf("%o", ptr) 320 | fmt.Sprintf("%x", ptr) 321 | fmt.Sprintf("%X", ptr) 322 | } 323 | 324 | func malformed() { 325 | fmt.Sprintf("%d", "example") 326 | fmt.Sprintf("%T", "example") 327 | fmt.Sprintf("%t", "example") 328 | fmt.Sprintf("%b", "example") 329 | fmt.Sprintf("%e", "example") 330 | fmt.Sprintf("%E", "example") 331 | fmt.Sprintf("%f", "example") 332 | fmt.Sprintf("%F", "example") 333 | fmt.Sprintf("%g", "example") 334 | fmt.Sprintf("%G", "example") 335 | fmt.Sprintf("%x", "example") 336 | fmt.Sprintf("%X", "example") 337 | 338 | fmt.Sprintf("%d", errSentinel) 339 | fmt.Sprintf("%T", errSentinel) 340 | fmt.Sprintf("%t", errSentinel) 341 | fmt.Sprintf("%b", errSentinel) 342 | fmt.Sprintf("%e", errSentinel) 343 | fmt.Sprintf("%E", errSentinel) 344 | fmt.Sprintf("%f", errSentinel) 345 | fmt.Sprintf("%F", errSentinel) 346 | fmt.Sprintf("%g", errSentinel) 347 | fmt.Sprintf("%G", errSentinel) 348 | fmt.Sprintf("%x", errSentinel) 349 | fmt.Sprintf("%X", errSentinel) 350 | 351 | fmt.Sprintf("%d", true) 352 | fmt.Sprintf("%T", true) 353 | fmt.Sprintf("%b", true) 354 | fmt.Sprintf("%e", true) 355 | fmt.Sprintf("%E", true) 356 | fmt.Sprintf("%f", true) 357 | fmt.Sprintf("%F", true) 358 | fmt.Sprintf("%g", true) 359 | fmt.Sprintf("%G", true) 360 | fmt.Sprintf("%x", true) 361 | fmt.Sprintf("%X", true) 362 | 363 | var bb []byte 364 | fmt.Sprintf("%d", bb) 365 | fmt.Sprintf("%T", bb) 366 | fmt.Sprintf("%t", bb) 367 | fmt.Sprintf("%b", bb) 368 | fmt.Sprintf("%e", bb) 369 | fmt.Sprintf("%E", bb) 370 | fmt.Sprintf("%f", bb) 371 | fmt.Sprintf("%F", bb) 372 | fmt.Sprintf("%g", bb) 373 | fmt.Sprintf("%G", bb) 374 | fmt.Sprintf("%X", bb) 375 | fmt.Sprintf("%v", bb) 376 | 377 | fmt.Sprintf("%T", 42) 378 | fmt.Sprintf("%t", 42) 379 | fmt.Sprintf("%b", 42) 380 | fmt.Sprintf("%e", 42) 381 | fmt.Sprintf("%E", 42) 382 | fmt.Sprintf("%f", 42) 383 | fmt.Sprintf("%F", 42) 384 | fmt.Sprintf("%g", 42) 385 | fmt.Sprintf("%G", 42) 386 | fmt.Sprintf("%x", 42) 387 | fmt.Sprintf("%X", 42) 388 | 389 | fmt.Sprintf("%T", uint(42)) 390 | fmt.Sprintf("%t", uint(42)) 391 | fmt.Sprintf("%b", uint(42)) 392 | fmt.Sprintf("%e", uint(42)) 393 | fmt.Sprintf("%E", uint(42)) 394 | fmt.Sprintf("%f", uint(42)) 395 | fmt.Sprintf("%F", uint(42)) 396 | fmt.Sprintf("%g", uint(42)) 397 | fmt.Sprintf("%G", uint(42)) 398 | fmt.Sprintf("%X", uint(42)) 399 | 400 | fmt.Sprintf("%d", 42.42) 401 | fmt.Sprintf("%d", map[string]string{}) 402 | fmt.Sprint(make(chan int)) 403 | fmt.Sprint([]int{1, 2, 3}) 404 | } 405 | -------------------------------------------------------------------------------- /analyzer/testdata/src/without-string-format/p.go.golden: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | import ( // want "Fix imports" 4 | "encoding/hex" 5 | "errors" 6 | "fmt" 7 | "io" 8 | "log" 9 | "net/url" 10 | "os" 11 | "strconv" 12 | "time" 13 | ) 14 | 15 | var errSentinel = errors.New("connection refused") 16 | 17 | func positive() { 18 | var s string 19 | fmt.Sprintf("%s", "hello") 20 | fmt.Sprintf("%v", "hello") 21 | fmt.Sprintf("hello") 22 | fmt.Sprint("hello") 23 | fmt.Sprintf("%s", s) 24 | fmt.Sprintf("%[1]s", s) 25 | fmt.Sprintf("%v", s) 26 | fmt.Sprint(s) 27 | errors.New("hello") // want "error-format: fmt.Errorf can be replaced with errors.New" 28 | 29 | fmt.Sprintf("Hello %s", s) 30 | fmt.Sprintf("%s says Hello", s) 31 | fmt.Sprintf("Hello says %[1]s", s) 32 | 33 | var err error 34 | fmt.Sprintf("%s", errSentinel) 35 | fmt.Sprintf("%v", errSentinel) 36 | fmt.Sprint(errSentinel) 37 | fmt.Sprintf("%s", io.EOF) 38 | fmt.Sprintf("%v", io.EOF) 39 | fmt.Sprint(io.EOF) 40 | fmt.Sprintf("%s", err) 41 | fmt.Sprintf("%v", err) 42 | fmt.Sprint(err) 43 | 44 | var b bool 45 | strconv.FormatBool(true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 46 | strconv.FormatBool(true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 47 | strconv.FormatBool(true) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 48 | strconv.FormatBool(false) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 49 | strconv.FormatBool(false) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 50 | strconv.FormatBool(false) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 51 | strconv.FormatBool(b) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 52 | strconv.FormatBool(b) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 53 | strconv.FormatBool(b) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 54 | 55 | var bs []byte 56 | var ba [3]byte 57 | hex.EncodeToString([]byte{'a'}) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 58 | hex.EncodeToString([]uint8{'b'}) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 59 | hex.EncodeToString(bs) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 60 | hex.EncodeToString(ba[:]) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 61 | 62 | var i int 63 | var i8 int8 64 | var i16 int16 65 | var i32 int32 66 | var i64 int64 67 | strconv.Itoa(i) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 68 | strconv.Itoa(i) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 69 | strconv.Itoa(i) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 70 | strconv.Itoa(42) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 71 | strconv.Itoa(42) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 72 | strconv.Itoa(42) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 73 | strconv.Itoa(int(i8)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 74 | strconv.Itoa(int(i8)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 75 | strconv.Itoa(int(i8)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 76 | strconv.Itoa(int(int8(42))) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 77 | strconv.Itoa(int(int8(42))) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 78 | strconv.Itoa(int(int8(42))) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 79 | strconv.Itoa(int(i16)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 80 | strconv.Itoa(int(i16)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 81 | strconv.Itoa(int(i16)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 82 | strconv.Itoa(int(int16(42))) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 83 | strconv.Itoa(int(int16(42))) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 84 | strconv.Itoa(int(int16(42))) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 85 | strconv.Itoa(int(i32)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 86 | strconv.Itoa(int(i32)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 87 | strconv.Itoa(int(i32)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 88 | strconv.Itoa(int(int32(42))) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 89 | strconv.Itoa(int(int32(42))) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 90 | strconv.Itoa(int(int32(42))) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 91 | strconv.FormatInt(i64, 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 92 | strconv.FormatInt(i64, 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 93 | strconv.FormatInt(i64, 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 94 | strconv.FormatInt(int64(42), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 95 | strconv.FormatInt(int64(42), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 96 | strconv.FormatInt(int64(42), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 97 | 98 | var ui uint 99 | var ui8 uint8 100 | var ui16 uint16 101 | var ui32 uint32 102 | var ui64 uint64 103 | strconv.FormatUint(uint64(ui), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 104 | strconv.FormatUint(uint64(ui), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 105 | strconv.FormatUint(uint64(ui), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 106 | strconv.FormatUint(uint64(uint(42)), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 107 | strconv.FormatUint(uint64(uint(42)), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 108 | strconv.FormatUint(uint64(uint(42)), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 109 | strconv.FormatUint(uint64(ui8), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 110 | strconv.FormatUint(uint64(ui8), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 111 | strconv.FormatUint(uint64(ui8), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 112 | strconv.FormatUint(uint64(uint8(42)), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 113 | strconv.FormatUint(uint64(uint8(42)), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 114 | strconv.FormatUint(uint64(uint8(42)), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 115 | strconv.FormatUint(uint64(ui16), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 116 | strconv.FormatUint(uint64(ui16), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 117 | strconv.FormatUint(uint64(ui16), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 118 | strconv.FormatUint(uint64(uint16(42)), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 119 | strconv.FormatUint(uint64(uint16(42)), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 120 | strconv.FormatUint(uint64(uint16(42)), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 121 | strconv.FormatUint(uint64(ui32), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 122 | strconv.FormatUint(uint64(ui32), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 123 | strconv.FormatUint(uint64(ui32), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 124 | strconv.FormatUint(uint64(uint32(42)), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 125 | strconv.FormatUint(uint64(uint32(42)), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 126 | strconv.FormatUint(uint64(uint32(42)), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 127 | strconv.FormatUint(ui64, 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 128 | strconv.FormatUint(ui64, 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 129 | strconv.FormatUint(ui64, 16) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 130 | strconv.FormatUint(uint64(uint(42)), 16) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 131 | strconv.FormatUint(ui64, 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 132 | strconv.FormatUint(uint64(42), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 133 | strconv.FormatUint(uint64(42), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 134 | strconv.FormatUint(uint64(42), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 135 | } 136 | 137 | func suggestedFixesTest() { 138 | _ = func() string { 139 | if false { 140 | return fmt.Sprint("replace me") 141 | } 142 | return fmt.Sprintf("%s", "replace me") 143 | } 144 | 145 | fmt.Println(fmt.Sprint(errSentinel)) 146 | fmt.Println(fmt.Sprintf("%s", errSentinel)) 147 | 148 | _ = func() string { 149 | switch 42 { 150 | case 1: 151 | return strconv.FormatBool(false) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 152 | case 2: 153 | return strconv.FormatBool(true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 154 | } 155 | return "" 156 | } 157 | 158 | var offset int 159 | params := url.Values{} 160 | params.Set("offset", strconv.Itoa(offset)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 161 | params.Set("offset", strconv.Itoa(offset)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 162 | 163 | var pubKey []byte 164 | if verifyPubKey := true; verifyPubKey { 165 | log.Println("pubkey=" + hex.EncodeToString(pubKey)) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 166 | } 167 | 168 | var metaHash [16]byte 169 | fn := fmt.Sprintf("%s.%x", "coverage.MetaFilePref", metaHash) 170 | _ = "tmp." + fn + strconv.FormatInt(time.Now().UnixNano(), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 171 | _ = "tmp." + fn + strconv.FormatInt(time.Now().UnixNano(), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 172 | 173 | var change struct{ User struct{ ID uint } } 174 | var userStr string 175 | if id := change.User.ID; id != 0 { 176 | userStr = strconv.FormatUint(uint64(id), 10) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 177 | userStr = strconv.FormatUint(uint64(id), 10) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 178 | } 179 | _ = userStr 180 | } 181 | 182 | func negative() { 183 | const val = "val%d" 184 | 185 | _ = int32(42) 186 | 187 | fmt.Scan(42) 188 | fmt.Scanf("%d", 42) 189 | fmt.Println("%d", 42) 190 | fmt.Printf("%d") 191 | fmt.Printf("%v") 192 | fmt.Printf("%d", 42) 193 | fmt.Printf("%s %d", "hello", 42) 194 | fmt.Errorf("this is %s", "complex") 195 | 196 | fmt.Fprint(os.Stdout, "%d", 42) 197 | fmt.Fprintf(os.Stdout, "test") 198 | fmt.Fprintf(os.Stdout, "%d") 199 | fmt.Fprintf(os.Stdout, "%v") 200 | fmt.Fprintf(os.Stdout, "%d", 42) 201 | fmt.Fprintf(os.Stdout, "%s %d", "hello", 42) 202 | 203 | fmt.Sprint("test", 42) 204 | fmt.Sprint(42, 42) 205 | fmt.Sprintf("%d", 42, 42) 206 | fmt.Sprintf("%#d", 42) 207 | fmt.Sprintf("value %d", 42) 208 | fmt.Sprintf(val, 42) 209 | fmt.Sprintf("%s %v", "hello", "world") 210 | fmt.Sprintf("%#v", 42) 211 | fmt.Sprintf("%T", struct{ string }{}) 212 | fmt.Sprintf("%%v", 42) 213 | fmt.Sprintf("%3d", 42) 214 | fmt.Sprintf("% d", 42) 215 | fmt.Sprintf("%-10d", 42) 216 | fmt.Sprintf("%s %[1]s", "hello") 217 | fmt.Sprintf("%[1]s %[1]s", "hello") 218 | fmt.Sprintf("%[2]d %[1]d\n", 11, 22) 219 | fmt.Sprintf("%[3]*.[2]*[1]f", 12.0, 2, 6) 220 | fmt.Sprintf("%d %d %#[1]x %#x", 16, 17) 221 | 222 | // Integer. 223 | fmt.Sprintf("%#x", uint64(42)) 224 | fmt.Sprintf("%#v", uint64(42)) 225 | fmt.Sprintf("%#b", 42) 226 | fmt.Sprintf("%#o", 42) 227 | fmt.Sprintf("%#x", 42) 228 | fmt.Sprintf("%#X", 42) 229 | 230 | fmt.Sprintf("%b", 42) 231 | fmt.Sprintf("%c", 42) 232 | fmt.Sprintf("%o", 42) 233 | fmt.Sprintf("%O", 42) 234 | fmt.Sprintf("%q", 42) 235 | fmt.Sprintf("%x", 42) 236 | fmt.Sprintf("%X", 42) 237 | 238 | // Floating point. 239 | fmt.Sprintf("%9f", 42.42) 240 | fmt.Sprintf("%.2f", 42.42) 241 | fmt.Sprintf("%.2f", 42.42) 242 | fmt.Sprintf("%9.2f", 42.42) 243 | fmt.Sprintf("%9.f", 42.42) 244 | fmt.Sprintf("%.3g", 42.42) 245 | 246 | fmt.Sprintf("%b", float32(42.42)) 247 | fmt.Sprintf("%e", float32(42.42)) 248 | fmt.Sprintf("%E", float32(42.42)) 249 | fmt.Sprintf("%f", float32(42.42)) 250 | fmt.Sprintf("%F", float32(42.42)) 251 | fmt.Sprintf("%g", float32(42.42)) 252 | fmt.Sprintf("%G", float32(42.42)) 253 | fmt.Sprintf("%x", float32(42.42)) 254 | fmt.Sprintf("%X", float32(42.42)) 255 | fmt.Sprintf("%v", float32(42.42)) 256 | 257 | fmt.Sprintf("%b", 42.42) 258 | fmt.Sprintf("%e", 42.42) 259 | fmt.Sprintf("%E", 42.42) 260 | fmt.Sprintf("%f", 42.42) 261 | fmt.Sprintf("%F", 42.42) 262 | fmt.Sprintf("%g", 42.42) 263 | fmt.Sprintf("%G", 42.42) 264 | fmt.Sprintf("%x", 42.42) 265 | fmt.Sprintf("%X", 42.42) 266 | fmt.Sprintf("%v", 42.42) 267 | 268 | fmt.Sprintf("%b", 42i+42) 269 | fmt.Sprintf("%e", 42i+42) 270 | fmt.Sprintf("%E", 42i+42) 271 | fmt.Sprintf("%f", 42i+42) 272 | fmt.Sprintf("%F", 42i+42) 273 | fmt.Sprintf("%g", 42i+42) 274 | fmt.Sprintf("%G", 42i+42) 275 | fmt.Sprintf("%x", 42i+42) 276 | fmt.Sprintf("%X", 42i+42) 277 | fmt.Sprintf("%v", 42i+42) 278 | 279 | // String & slice of bytes. 280 | fmt.Sprintf("%q", "hello") 281 | fmt.Sprintf("%#q", `"hello"`) 282 | fmt.Sprintf("%+q", "hello") 283 | fmt.Sprintf("%X", "hello") 284 | 285 | // Slice. 286 | fmt.Sprintf("%x", []uint16{'d'}) 287 | fmt.Sprintf("%x", []uint32{'d'}) 288 | fmt.Sprintf("%x", []uint64{'d'}) 289 | fmt.Sprintf("%x", []uint{'d'}) 290 | fmt.Sprintf("%x", [1]byte{'c'}) 291 | fmt.Sprintf("%x", [1]uint8{'d'}) 292 | fmt.Sprintf("%x", [1]uint16{'d'}) 293 | fmt.Sprintf("%x", [1]uint32{'d'}) 294 | fmt.Sprintf("%x", [1]uint64{'d'}) 295 | fmt.Sprintf("%x", [1]uint{'d'}) 296 | fmt.Sprintf("%x", []int8{1}) 297 | fmt.Sprintf("%x", []int16{1}) 298 | fmt.Sprintf("%x", []int32{1}) 299 | fmt.Sprintf("%x", []int64{1}) 300 | fmt.Sprintf("%x", []int{1}) 301 | fmt.Sprintf("%x", [...]int8{1}) 302 | fmt.Sprintf("%x", [...]int16{1}) 303 | fmt.Sprintf("%x", [...]int32{1}) 304 | fmt.Sprintf("%x", [...]int64{1}) 305 | fmt.Sprintf("%x", [...]int{1}) 306 | fmt.Sprintf("%x", []string{"hello"}) 307 | fmt.Sprintf("%x", []rune{'a'}) 308 | 309 | fmt.Sprintf("% x", []byte{1, 2, 3}) 310 | fmt.Sprintf("% X", []byte{1, 2, 3}) 311 | fmt.Sprintf("%p", []byte{1, 2, 3}) 312 | fmt.Sprintf("%#p", []byte{1, 2, 3}) 313 | 314 | // Pointer. 315 | var ptr *int 316 | fmt.Sprintf("%v", ptr) 317 | fmt.Sprintf("%b", ptr) 318 | fmt.Sprintf("%d", ptr) 319 | fmt.Sprintf("%o", ptr) 320 | fmt.Sprintf("%x", ptr) 321 | fmt.Sprintf("%X", ptr) 322 | } 323 | 324 | func malformed() { 325 | fmt.Sprintf("%d", "example") 326 | fmt.Sprintf("%T", "example") 327 | fmt.Sprintf("%t", "example") 328 | fmt.Sprintf("%b", "example") 329 | fmt.Sprintf("%e", "example") 330 | fmt.Sprintf("%E", "example") 331 | fmt.Sprintf("%f", "example") 332 | fmt.Sprintf("%F", "example") 333 | fmt.Sprintf("%g", "example") 334 | fmt.Sprintf("%G", "example") 335 | fmt.Sprintf("%x", "example") 336 | fmt.Sprintf("%X", "example") 337 | 338 | fmt.Sprintf("%d", errSentinel) 339 | fmt.Sprintf("%T", errSentinel) 340 | fmt.Sprintf("%t", errSentinel) 341 | fmt.Sprintf("%b", errSentinel) 342 | fmt.Sprintf("%e", errSentinel) 343 | fmt.Sprintf("%E", errSentinel) 344 | fmt.Sprintf("%f", errSentinel) 345 | fmt.Sprintf("%F", errSentinel) 346 | fmt.Sprintf("%g", errSentinel) 347 | fmt.Sprintf("%G", errSentinel) 348 | fmt.Sprintf("%x", errSentinel) 349 | fmt.Sprintf("%X", errSentinel) 350 | 351 | fmt.Sprintf("%d", true) 352 | fmt.Sprintf("%T", true) 353 | fmt.Sprintf("%b", true) 354 | fmt.Sprintf("%e", true) 355 | fmt.Sprintf("%E", true) 356 | fmt.Sprintf("%f", true) 357 | fmt.Sprintf("%F", true) 358 | fmt.Sprintf("%g", true) 359 | fmt.Sprintf("%G", true) 360 | fmt.Sprintf("%x", true) 361 | fmt.Sprintf("%X", true) 362 | 363 | var bb []byte 364 | fmt.Sprintf("%d", bb) 365 | fmt.Sprintf("%T", bb) 366 | fmt.Sprintf("%t", bb) 367 | fmt.Sprintf("%b", bb) 368 | fmt.Sprintf("%e", bb) 369 | fmt.Sprintf("%E", bb) 370 | fmt.Sprintf("%f", bb) 371 | fmt.Sprintf("%F", bb) 372 | fmt.Sprintf("%g", bb) 373 | fmt.Sprintf("%G", bb) 374 | fmt.Sprintf("%X", bb) 375 | fmt.Sprintf("%v", bb) 376 | 377 | fmt.Sprintf("%T", 42) 378 | fmt.Sprintf("%t", 42) 379 | fmt.Sprintf("%b", 42) 380 | fmt.Sprintf("%e", 42) 381 | fmt.Sprintf("%E", 42) 382 | fmt.Sprintf("%f", 42) 383 | fmt.Sprintf("%F", 42) 384 | fmt.Sprintf("%g", 42) 385 | fmt.Sprintf("%G", 42) 386 | fmt.Sprintf("%x", 42) 387 | fmt.Sprintf("%X", 42) 388 | 389 | fmt.Sprintf("%T", uint(42)) 390 | fmt.Sprintf("%t", uint(42)) 391 | fmt.Sprintf("%b", uint(42)) 392 | fmt.Sprintf("%e", uint(42)) 393 | fmt.Sprintf("%E", uint(42)) 394 | fmt.Sprintf("%f", uint(42)) 395 | fmt.Sprintf("%F", uint(42)) 396 | fmt.Sprintf("%g", uint(42)) 397 | fmt.Sprintf("%G", uint(42)) 398 | fmt.Sprintf("%X", uint(42)) 399 | 400 | fmt.Sprintf("%d", 42.42) 401 | fmt.Sprintf("%d", map[string]string{}) 402 | fmt.Sprint(make(chan int)) 403 | fmt.Sprint([]int{1, 2, 3}) 404 | } 405 | -------------------------------------------------------------------------------- /analyzer/testdata/src/without-hex-format/p.go: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | import ( // want "Fix imports" 4 | "errors" 5 | "fmt" 6 | "io" 7 | "log" 8 | "net/url" 9 | "os" 10 | "time" 11 | ) 12 | 13 | var errSentinel = errors.New("connection refused") 14 | 15 | func positive() { 16 | var s string 17 | fmt.Sprintf("%s", "hello") // want "string-format: fmt.Sprintf can be replaced with just using the string" 18 | fmt.Sprintf("%v", "hello") // want "string-format: fmt.Sprintf can be replaced with just using the string" 19 | fmt.Sprintf("hello") // want "string-format: fmt.Sprintf can be replaced with just using the string" 20 | fmt.Sprint("hello") // want "string-format: fmt.Sprint can be replaced with just using the string" 21 | fmt.Sprintf("%s", s) // want "string-format: fmt.Sprintf can be replaced with just using the string" 22 | fmt.Sprintf("%[1]s", s) // want "string-format: fmt.Sprintf can be replaced with just using the string" 23 | fmt.Sprintf("%v", s) // want "string-format: fmt.Sprintf can be replaced with just using the string" 24 | fmt.Sprint(s) // want "string-format: fmt.Sprint can be replaced with just using the string" 25 | fmt.Errorf("hello") // want "error-format: fmt.Errorf can be replaced with errors.New" 26 | 27 | fmt.Sprintf("Hello %s", s) // want "string-format: fmt.Sprintf can be replaced with string concatenation" 28 | fmt.Sprintf("%s says Hello", s) // want "string-format: fmt.Sprintf can be replaced with string concatenation" 29 | fmt.Sprintf("Hello says %[1]s", s) // want "string-format: fmt.Sprintf can be replaced with string concatenation" 30 | 31 | var err error 32 | fmt.Sprintf("%s", errSentinel) 33 | fmt.Sprintf("%v", errSentinel) 34 | fmt.Sprint(errSentinel) 35 | fmt.Sprintf("%s", io.EOF) 36 | fmt.Sprintf("%v", io.EOF) 37 | fmt.Sprint(io.EOF) 38 | fmt.Sprintf("%s", err) 39 | fmt.Sprintf("%v", err) 40 | fmt.Sprint(err) 41 | 42 | var b bool 43 | fmt.Sprintf("%t", true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 44 | fmt.Sprintf("%v", true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 45 | fmt.Sprint(true) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 46 | fmt.Sprintf("%t", false) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 47 | fmt.Sprintf("%v", false) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 48 | fmt.Sprint(false) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 49 | fmt.Sprintf("%t", b) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 50 | fmt.Sprintf("%v", b) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 51 | fmt.Sprint(b) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 52 | 53 | var bs []byte 54 | var ba [3]byte 55 | fmt.Sprintf("%x", []byte{'a'}) 56 | fmt.Sprintf("%x", []uint8{'b'}) 57 | fmt.Sprintf("%x", bs) 58 | fmt.Sprintf("%x", ba) 59 | 60 | var i int 61 | var i8 int8 62 | var i16 int16 63 | var i32 int32 64 | var i64 int64 65 | fmt.Sprintf("%d", i) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 66 | fmt.Sprintf("%v", i) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 67 | fmt.Sprint(i) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 68 | fmt.Sprintf("%d", 42) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 69 | fmt.Sprintf("%v", 42) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 70 | fmt.Sprint(42) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 71 | fmt.Sprintf("%d", i8) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 72 | fmt.Sprintf("%v", i8) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 73 | fmt.Sprint(i8) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 74 | fmt.Sprintf("%d", int8(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 75 | fmt.Sprintf("%v", int8(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 76 | fmt.Sprint(int8(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 77 | fmt.Sprintf("%d", i16) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 78 | fmt.Sprintf("%v", i16) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 79 | fmt.Sprint(i16) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 80 | fmt.Sprintf("%d", int16(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 81 | fmt.Sprintf("%v", int16(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 82 | fmt.Sprint(int16(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 83 | fmt.Sprintf("%d", i32) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 84 | fmt.Sprintf("%v", i32) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 85 | fmt.Sprint(i32) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 86 | fmt.Sprintf("%d", int32(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 87 | fmt.Sprintf("%v", int32(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 88 | fmt.Sprint(int32(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 89 | fmt.Sprintf("%d", i64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 90 | fmt.Sprintf("%v", i64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 91 | fmt.Sprint(i64) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 92 | fmt.Sprintf("%d", int64(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 93 | fmt.Sprintf("%v", int64(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 94 | fmt.Sprint(int64(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 95 | 96 | var ui uint 97 | var ui8 uint8 98 | var ui16 uint16 99 | var ui32 uint32 100 | var ui64 uint64 101 | fmt.Sprintf("%d", ui) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 102 | fmt.Sprintf("%v", ui) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 103 | fmt.Sprint(ui) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 104 | fmt.Sprintf("%d", uint(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 105 | fmt.Sprintf("%v", uint(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 106 | fmt.Sprint(uint(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 107 | fmt.Sprintf("%d", ui8) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 108 | fmt.Sprintf("%v", ui8) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 109 | fmt.Sprint(ui8) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 110 | fmt.Sprintf("%d", uint8(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 111 | fmt.Sprintf("%v", uint8(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 112 | fmt.Sprint(uint8(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 113 | fmt.Sprintf("%d", ui16) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 114 | fmt.Sprintf("%v", ui16) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 115 | fmt.Sprint(ui16) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 116 | fmt.Sprintf("%d", uint16(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 117 | fmt.Sprintf("%v", uint16(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 118 | fmt.Sprint(uint16(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 119 | fmt.Sprintf("%d", ui32) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 120 | fmt.Sprintf("%v", ui32) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 121 | fmt.Sprint(ui32) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 122 | fmt.Sprintf("%d", uint32(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 123 | fmt.Sprintf("%v", uint32(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 124 | fmt.Sprint(uint32(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 125 | fmt.Sprintf("%d", ui64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 126 | fmt.Sprintf("%v", ui64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 127 | fmt.Sprintf("%x", ui64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 128 | fmt.Sprintf("%x", uint(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 129 | fmt.Sprint(ui64) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 130 | fmt.Sprintf("%d", uint64(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 131 | fmt.Sprintf("%v", uint64(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 132 | fmt.Sprint(uint64(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 133 | } 134 | 135 | func suggestedFixesTest() { 136 | _ = func() string { 137 | if false { 138 | return fmt.Sprint("replace me") // want "string-format: fmt.Sprint can be replaced with just using the string" 139 | } 140 | return fmt.Sprintf("%s", "replace me") // want "string-format: fmt.Sprintf can be replaced with just using the string" 141 | } 142 | 143 | fmt.Println(fmt.Sprint(errSentinel)) 144 | fmt.Println(fmt.Sprintf("%s", errSentinel)) 145 | 146 | _ = func() string { 147 | switch 42 { 148 | case 1: 149 | return fmt.Sprint(false) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 150 | case 2: 151 | return fmt.Sprintf("%t", true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 152 | } 153 | return "" 154 | } 155 | 156 | var offset int 157 | params := url.Values{} 158 | params.Set("offset", fmt.Sprintf("%d", offset)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 159 | params.Set("offset", fmt.Sprint(offset)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 160 | 161 | var pubKey []byte 162 | if verifyPubKey := true; verifyPubKey { 163 | log.Println("pubkey=" + fmt.Sprintf("%x", pubKey)) 164 | } 165 | 166 | var metaHash [16]byte 167 | fn := fmt.Sprintf("%s.%x", "coverage.MetaFilePref", metaHash) 168 | _ = "tmp." + fn + fmt.Sprintf("%d", time.Now().UnixNano()) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 169 | _ = "tmp." + fn + fmt.Sprint(time.Now().UnixNano()) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 170 | 171 | var change struct{ User struct{ ID uint } } 172 | var userStr string 173 | if id := change.User.ID; id != 0 { 174 | userStr = fmt.Sprintf("%d", id) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 175 | userStr = fmt.Sprint(id) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 176 | } 177 | _ = userStr 178 | } 179 | 180 | func negative() { 181 | const val = "val%d" 182 | 183 | _ = int32(42) 184 | 185 | fmt.Scan(42) 186 | fmt.Scanf("%d", 42) 187 | fmt.Println("%d", 42) 188 | fmt.Printf("%d") 189 | fmt.Printf("%v") 190 | fmt.Printf("%d", 42) 191 | fmt.Printf("%s %d", "hello", 42) 192 | fmt.Errorf("this is %s", "complex") 193 | 194 | fmt.Fprint(os.Stdout, "%d", 42) 195 | fmt.Fprintf(os.Stdout, "test") 196 | fmt.Fprintf(os.Stdout, "%d") 197 | fmt.Fprintf(os.Stdout, "%v") 198 | fmt.Fprintf(os.Stdout, "%d", 42) 199 | fmt.Fprintf(os.Stdout, "%s %d", "hello", 42) 200 | 201 | fmt.Sprint("test", 42) 202 | fmt.Sprint(42, 42) 203 | fmt.Sprintf("%d", 42, 42) 204 | fmt.Sprintf("%#d", 42) 205 | fmt.Sprintf("value %d", 42) 206 | fmt.Sprintf(val, 42) 207 | fmt.Sprintf("%s %v", "hello", "world") 208 | fmt.Sprintf("%#v", 42) 209 | fmt.Sprintf("%T", struct{ string }{}) 210 | fmt.Sprintf("%%v", 42) 211 | fmt.Sprintf("%3d", 42) 212 | fmt.Sprintf("% d", 42) 213 | fmt.Sprintf("%-10d", 42) 214 | fmt.Sprintf("%s %[1]s", "hello") 215 | fmt.Sprintf("%[1]s %[1]s", "hello") 216 | fmt.Sprintf("%[2]d %[1]d\n", 11, 22) 217 | fmt.Sprintf("%[3]*.[2]*[1]f", 12.0, 2, 6) 218 | fmt.Sprintf("%d %d %#[1]x %#x", 16, 17) 219 | 220 | // Integer. 221 | fmt.Sprintf("%#x", uint64(42)) 222 | fmt.Sprintf("%#v", uint64(42)) 223 | fmt.Sprintf("%#b", 42) 224 | fmt.Sprintf("%#o", 42) 225 | fmt.Sprintf("%#x", 42) 226 | fmt.Sprintf("%#X", 42) 227 | 228 | fmt.Sprintf("%b", 42) 229 | fmt.Sprintf("%c", 42) 230 | fmt.Sprintf("%o", 42) 231 | fmt.Sprintf("%O", 42) 232 | fmt.Sprintf("%q", 42) 233 | fmt.Sprintf("%x", 42) 234 | fmt.Sprintf("%X", 42) 235 | 236 | // Floating point. 237 | fmt.Sprintf("%9f", 42.42) 238 | fmt.Sprintf("%.2f", 42.42) 239 | fmt.Sprintf("%.2f", 42.42) 240 | fmt.Sprintf("%9.2f", 42.42) 241 | fmt.Sprintf("%9.f", 42.42) 242 | fmt.Sprintf("%.3g", 42.42) 243 | 244 | fmt.Sprintf("%b", float32(42.42)) 245 | fmt.Sprintf("%e", float32(42.42)) 246 | fmt.Sprintf("%E", float32(42.42)) 247 | fmt.Sprintf("%f", float32(42.42)) 248 | fmt.Sprintf("%F", float32(42.42)) 249 | fmt.Sprintf("%g", float32(42.42)) 250 | fmt.Sprintf("%G", float32(42.42)) 251 | fmt.Sprintf("%x", float32(42.42)) 252 | fmt.Sprintf("%X", float32(42.42)) 253 | fmt.Sprintf("%v", float32(42.42)) 254 | 255 | fmt.Sprintf("%b", 42.42) 256 | fmt.Sprintf("%e", 42.42) 257 | fmt.Sprintf("%E", 42.42) 258 | fmt.Sprintf("%f", 42.42) 259 | fmt.Sprintf("%F", 42.42) 260 | fmt.Sprintf("%g", 42.42) 261 | fmt.Sprintf("%G", 42.42) 262 | fmt.Sprintf("%x", 42.42) 263 | fmt.Sprintf("%X", 42.42) 264 | fmt.Sprintf("%v", 42.42) 265 | 266 | fmt.Sprintf("%b", 42i+42) 267 | fmt.Sprintf("%e", 42i+42) 268 | fmt.Sprintf("%E", 42i+42) 269 | fmt.Sprintf("%f", 42i+42) 270 | fmt.Sprintf("%F", 42i+42) 271 | fmt.Sprintf("%g", 42i+42) 272 | fmt.Sprintf("%G", 42i+42) 273 | fmt.Sprintf("%x", 42i+42) 274 | fmt.Sprintf("%X", 42i+42) 275 | fmt.Sprintf("%v", 42i+42) 276 | 277 | // String & slice of bytes. 278 | fmt.Sprintf("%q", "hello") 279 | fmt.Sprintf("%#q", `"hello"`) 280 | fmt.Sprintf("%+q", "hello") 281 | fmt.Sprintf("%X", "hello") 282 | 283 | // Slice. 284 | fmt.Sprintf("%x", []uint16{'d'}) 285 | fmt.Sprintf("%x", []uint32{'d'}) 286 | fmt.Sprintf("%x", []uint64{'d'}) 287 | fmt.Sprintf("%x", []uint{'d'}) 288 | fmt.Sprintf("%x", [1]byte{'c'}) 289 | fmt.Sprintf("%x", [1]uint8{'d'}) 290 | fmt.Sprintf("%x", [1]uint16{'d'}) 291 | fmt.Sprintf("%x", [1]uint32{'d'}) 292 | fmt.Sprintf("%x", [1]uint64{'d'}) 293 | fmt.Sprintf("%x", [1]uint{'d'}) 294 | fmt.Sprintf("%x", []int8{1}) 295 | fmt.Sprintf("%x", []int16{1}) 296 | fmt.Sprintf("%x", []int32{1}) 297 | fmt.Sprintf("%x", []int64{1}) 298 | fmt.Sprintf("%x", []int{1}) 299 | fmt.Sprintf("%x", [...]int8{1}) 300 | fmt.Sprintf("%x", [...]int16{1}) 301 | fmt.Sprintf("%x", [...]int32{1}) 302 | fmt.Sprintf("%x", [...]int64{1}) 303 | fmt.Sprintf("%x", [...]int{1}) 304 | fmt.Sprintf("%x", []string{"hello"}) 305 | fmt.Sprintf("%x", []rune{'a'}) 306 | 307 | fmt.Sprintf("% x", []byte{1, 2, 3}) 308 | fmt.Sprintf("% X", []byte{1, 2, 3}) 309 | fmt.Sprintf("%p", []byte{1, 2, 3}) 310 | fmt.Sprintf("%#p", []byte{1, 2, 3}) 311 | 312 | // Pointer. 313 | var ptr *int 314 | fmt.Sprintf("%v", ptr) 315 | fmt.Sprintf("%b", ptr) 316 | fmt.Sprintf("%d", ptr) 317 | fmt.Sprintf("%o", ptr) 318 | fmt.Sprintf("%x", ptr) 319 | fmt.Sprintf("%X", ptr) 320 | } 321 | 322 | func malformed() { 323 | fmt.Sprintf("%d", "example") 324 | fmt.Sprintf("%T", "example") 325 | fmt.Sprintf("%t", "example") 326 | fmt.Sprintf("%b", "example") 327 | fmt.Sprintf("%e", "example") 328 | fmt.Sprintf("%E", "example") 329 | fmt.Sprintf("%f", "example") 330 | fmt.Sprintf("%F", "example") 331 | fmt.Sprintf("%g", "example") 332 | fmt.Sprintf("%G", "example") 333 | fmt.Sprintf("%x", "example") 334 | fmt.Sprintf("%X", "example") 335 | 336 | fmt.Sprintf("%d", errSentinel) 337 | fmt.Sprintf("%T", errSentinel) 338 | fmt.Sprintf("%t", errSentinel) 339 | fmt.Sprintf("%b", errSentinel) 340 | fmt.Sprintf("%e", errSentinel) 341 | fmt.Sprintf("%E", errSentinel) 342 | fmt.Sprintf("%f", errSentinel) 343 | fmt.Sprintf("%F", errSentinel) 344 | fmt.Sprintf("%g", errSentinel) 345 | fmt.Sprintf("%G", errSentinel) 346 | fmt.Sprintf("%x", errSentinel) 347 | fmt.Sprintf("%X", errSentinel) 348 | 349 | fmt.Sprintf("%d", true) 350 | fmt.Sprintf("%T", true) 351 | fmt.Sprintf("%b", true) 352 | fmt.Sprintf("%e", true) 353 | fmt.Sprintf("%E", true) 354 | fmt.Sprintf("%f", true) 355 | fmt.Sprintf("%F", true) 356 | fmt.Sprintf("%g", true) 357 | fmt.Sprintf("%G", true) 358 | fmt.Sprintf("%x", true) 359 | fmt.Sprintf("%X", true) 360 | 361 | var bb []byte 362 | fmt.Sprintf("%d", bb) 363 | fmt.Sprintf("%T", bb) 364 | fmt.Sprintf("%t", bb) 365 | fmt.Sprintf("%b", bb) 366 | fmt.Sprintf("%e", bb) 367 | fmt.Sprintf("%E", bb) 368 | fmt.Sprintf("%f", bb) 369 | fmt.Sprintf("%F", bb) 370 | fmt.Sprintf("%g", bb) 371 | fmt.Sprintf("%G", bb) 372 | fmt.Sprintf("%X", bb) 373 | fmt.Sprintf("%v", bb) 374 | 375 | fmt.Sprintf("%T", 42) 376 | fmt.Sprintf("%t", 42) 377 | fmt.Sprintf("%b", 42) 378 | fmt.Sprintf("%e", 42) 379 | fmt.Sprintf("%E", 42) 380 | fmt.Sprintf("%f", 42) 381 | fmt.Sprintf("%F", 42) 382 | fmt.Sprintf("%g", 42) 383 | fmt.Sprintf("%G", 42) 384 | fmt.Sprintf("%x", 42) 385 | fmt.Sprintf("%X", 42) 386 | 387 | fmt.Sprintf("%T", uint(42)) 388 | fmt.Sprintf("%t", uint(42)) 389 | fmt.Sprintf("%b", uint(42)) 390 | fmt.Sprintf("%e", uint(42)) 391 | fmt.Sprintf("%E", uint(42)) 392 | fmt.Sprintf("%f", uint(42)) 393 | fmt.Sprintf("%F", uint(42)) 394 | fmt.Sprintf("%g", uint(42)) 395 | fmt.Sprintf("%G", uint(42)) 396 | fmt.Sprintf("%X", uint(42)) 397 | 398 | fmt.Sprintf("%d", 42.42) 399 | fmt.Sprintf("%d", map[string]string{}) 400 | fmt.Sprint(make(chan int)) 401 | fmt.Sprint([]int{1, 2, 3}) 402 | } 403 | -------------------------------------------------------------------------------- /analyzer/testdata/src/without-strconcat/p.go: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | import ( // want "Fix imports" 4 | "errors" 5 | "fmt" 6 | "io" 7 | "log" 8 | "net/url" 9 | "os" 10 | "time" 11 | ) 12 | 13 | var errSentinel = errors.New("connection refused") 14 | 15 | func positive() { 16 | var s string 17 | fmt.Sprintf("%s", "hello") // want "string-format: fmt.Sprintf can be replaced with just using the string" 18 | fmt.Sprintf("%v", "hello") // want "string-format: fmt.Sprintf can be replaced with just using the string" 19 | fmt.Sprintf("hello") // want "string-format: fmt.Sprintf can be replaced with just using the string" 20 | fmt.Sprint("hello") // want "string-format: fmt.Sprint can be replaced with just using the string" 21 | fmt.Sprintf("%s", s) // want "string-format: fmt.Sprintf can be replaced with just using the string" 22 | fmt.Sprintf("%[1]s", s) // want "string-format: fmt.Sprintf can be replaced with just using the string" 23 | fmt.Sprintf("%v", s) // want "string-format: fmt.Sprintf can be replaced with just using the string" 24 | fmt.Sprint(s) // want "string-format: fmt.Sprint can be replaced with just using the string" 25 | fmt.Errorf("hello") // want "error-format: fmt.Errorf can be replaced with errors.New" 26 | 27 | fmt.Sprintf("Hello %s", s) 28 | fmt.Sprintf("%s says Hello", s) 29 | fmt.Sprintf("Hello says %[1]s", s) 30 | 31 | var err error 32 | fmt.Sprintf("%s", errSentinel) 33 | fmt.Sprintf("%v", errSentinel) 34 | fmt.Sprint(errSentinel) 35 | fmt.Sprintf("%s", io.EOF) 36 | fmt.Sprintf("%v", io.EOF) 37 | fmt.Sprint(io.EOF) 38 | fmt.Sprintf("%s", err) 39 | fmt.Sprintf("%v", err) 40 | fmt.Sprint(err) 41 | 42 | var b bool 43 | fmt.Sprintf("%t", true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 44 | fmt.Sprintf("%v", true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 45 | fmt.Sprint(true) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 46 | fmt.Sprintf("%t", false) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 47 | fmt.Sprintf("%v", false) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 48 | fmt.Sprint(false) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 49 | fmt.Sprintf("%t", b) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 50 | fmt.Sprintf("%v", b) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 51 | fmt.Sprint(b) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 52 | 53 | var bs []byte 54 | var ba [3]byte 55 | fmt.Sprintf("%x", []byte{'a'}) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 56 | fmt.Sprintf("%x", []uint8{'b'}) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 57 | fmt.Sprintf("%x", bs) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 58 | fmt.Sprintf("%x", ba) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 59 | 60 | var i int 61 | var i8 int8 62 | var i16 int16 63 | var i32 int32 64 | var i64 int64 65 | fmt.Sprintf("%d", i) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 66 | fmt.Sprintf("%v", i) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 67 | fmt.Sprint(i) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 68 | fmt.Sprintf("%d", 42) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 69 | fmt.Sprintf("%v", 42) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 70 | fmt.Sprint(42) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 71 | fmt.Sprintf("%d", i8) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 72 | fmt.Sprintf("%v", i8) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 73 | fmt.Sprint(i8) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 74 | fmt.Sprintf("%d", int8(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 75 | fmt.Sprintf("%v", int8(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 76 | fmt.Sprint(int8(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 77 | fmt.Sprintf("%d", i16) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 78 | fmt.Sprintf("%v", i16) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 79 | fmt.Sprint(i16) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 80 | fmt.Sprintf("%d", int16(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 81 | fmt.Sprintf("%v", int16(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 82 | fmt.Sprint(int16(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 83 | fmt.Sprintf("%d", i32) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 84 | fmt.Sprintf("%v", i32) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 85 | fmt.Sprint(i32) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 86 | fmt.Sprintf("%d", int32(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 87 | fmt.Sprintf("%v", int32(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 88 | fmt.Sprint(int32(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 89 | fmt.Sprintf("%d", i64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 90 | fmt.Sprintf("%v", i64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 91 | fmt.Sprint(i64) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 92 | fmt.Sprintf("%d", int64(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 93 | fmt.Sprintf("%v", int64(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 94 | fmt.Sprint(int64(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 95 | 96 | var ui uint 97 | var ui8 uint8 98 | var ui16 uint16 99 | var ui32 uint32 100 | var ui64 uint64 101 | fmt.Sprintf("%d", ui) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 102 | fmt.Sprintf("%v", ui) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 103 | fmt.Sprint(ui) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 104 | fmt.Sprintf("%d", uint(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 105 | fmt.Sprintf("%v", uint(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 106 | fmt.Sprint(uint(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 107 | fmt.Sprintf("%d", ui8) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 108 | fmt.Sprintf("%v", ui8) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 109 | fmt.Sprint(ui8) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 110 | fmt.Sprintf("%d", uint8(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 111 | fmt.Sprintf("%v", uint8(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 112 | fmt.Sprint(uint8(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 113 | fmt.Sprintf("%d", ui16) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 114 | fmt.Sprintf("%v", ui16) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 115 | fmt.Sprint(ui16) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 116 | fmt.Sprintf("%d", uint16(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 117 | fmt.Sprintf("%v", uint16(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 118 | fmt.Sprint(uint16(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 119 | fmt.Sprintf("%d", ui32) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 120 | fmt.Sprintf("%v", ui32) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 121 | fmt.Sprint(ui32) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 122 | fmt.Sprintf("%d", uint32(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 123 | fmt.Sprintf("%v", uint32(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 124 | fmt.Sprint(uint32(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 125 | fmt.Sprintf("%d", ui64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 126 | fmt.Sprintf("%v", ui64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 127 | fmt.Sprintf("%x", ui64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 128 | fmt.Sprintf("%x", uint(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 129 | fmt.Sprint(ui64) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 130 | fmt.Sprintf("%d", uint64(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 131 | fmt.Sprintf("%v", uint64(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 132 | fmt.Sprint(uint64(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 133 | } 134 | 135 | func suggestedFixesTest() { 136 | _ = func() string { 137 | if false { 138 | return fmt.Sprint("replace me") // want "string-format: fmt.Sprint can be replaced with just using the string" 139 | } 140 | return fmt.Sprintf("%s", "replace me") // want "string-format: fmt.Sprintf can be replaced with just using the string" 141 | } 142 | 143 | fmt.Println(fmt.Sprint(errSentinel)) 144 | fmt.Println(fmt.Sprintf("%s", errSentinel)) 145 | 146 | _ = func() string { 147 | switch 42 { 148 | case 1: 149 | return fmt.Sprint(false) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 150 | case 2: 151 | return fmt.Sprintf("%t", true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 152 | } 153 | return "" 154 | } 155 | 156 | var offset int 157 | params := url.Values{} 158 | params.Set("offset", fmt.Sprintf("%d", offset)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 159 | params.Set("offset", fmt.Sprint(offset)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 160 | 161 | var pubKey []byte 162 | if verifyPubKey := true; verifyPubKey { 163 | log.Println("pubkey=" + fmt.Sprintf("%x", pubKey)) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 164 | } 165 | 166 | var metaHash [16]byte 167 | fn := fmt.Sprintf("%s.%x", "coverage.MetaFilePref", metaHash) 168 | _ = "tmp." + fn + fmt.Sprintf("%d", time.Now().UnixNano()) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 169 | _ = "tmp." + fn + fmt.Sprint(time.Now().UnixNano()) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 170 | 171 | var change struct{ User struct{ ID uint } } 172 | var userStr string 173 | if id := change.User.ID; id != 0 { 174 | userStr = fmt.Sprintf("%d", id) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 175 | userStr = fmt.Sprint(id) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 176 | } 177 | _ = userStr 178 | } 179 | 180 | func negative() { 181 | const val = "val%d" 182 | 183 | _ = int32(42) 184 | 185 | fmt.Scan(42) 186 | fmt.Scanf("%d", 42) 187 | fmt.Println("%d", 42) 188 | fmt.Printf("%d") 189 | fmt.Printf("%v") 190 | fmt.Printf("%d", 42) 191 | fmt.Printf("%s %d", "hello", 42) 192 | fmt.Errorf("this is %s", "complex") 193 | 194 | fmt.Fprint(os.Stdout, "%d", 42) 195 | fmt.Fprintf(os.Stdout, "test") 196 | fmt.Fprintf(os.Stdout, "%d") 197 | fmt.Fprintf(os.Stdout, "%v") 198 | fmt.Fprintf(os.Stdout, "%d", 42) 199 | fmt.Fprintf(os.Stdout, "%s %d", "hello", 42) 200 | 201 | fmt.Sprint("test", 42) 202 | fmt.Sprint(42, 42) 203 | fmt.Sprintf("%d", 42, 42) 204 | fmt.Sprintf("%#d", 42) 205 | fmt.Sprintf("value %d", 42) 206 | fmt.Sprintf(val, 42) 207 | fmt.Sprintf("%s %v", "hello", "world") 208 | fmt.Sprintf("%#v", 42) 209 | fmt.Sprintf("%T", struct{ string }{}) 210 | fmt.Sprintf("%%v", 42) 211 | fmt.Sprintf("%3d", 42) 212 | fmt.Sprintf("% d", 42) 213 | fmt.Sprintf("%-10d", 42) 214 | fmt.Sprintf("%s %[1]s", "hello") 215 | fmt.Sprintf("%[1]s %[1]s", "hello") 216 | fmt.Sprintf("%[2]d %[1]d\n", 11, 22) 217 | fmt.Sprintf("%[3]*.[2]*[1]f", 12.0, 2, 6) 218 | fmt.Sprintf("%d %d %#[1]x %#x", 16, 17) 219 | 220 | // Integer. 221 | fmt.Sprintf("%#x", uint64(42)) 222 | fmt.Sprintf("%#v", uint64(42)) 223 | fmt.Sprintf("%#b", 42) 224 | fmt.Sprintf("%#o", 42) 225 | fmt.Sprintf("%#x", 42) 226 | fmt.Sprintf("%#X", 42) 227 | 228 | fmt.Sprintf("%b", 42) 229 | fmt.Sprintf("%c", 42) 230 | fmt.Sprintf("%o", 42) 231 | fmt.Sprintf("%O", 42) 232 | fmt.Sprintf("%q", 42) 233 | fmt.Sprintf("%x", 42) 234 | fmt.Sprintf("%X", 42) 235 | 236 | // Floating point. 237 | fmt.Sprintf("%9f", 42.42) 238 | fmt.Sprintf("%.2f", 42.42) 239 | fmt.Sprintf("%.2f", 42.42) 240 | fmt.Sprintf("%9.2f", 42.42) 241 | fmt.Sprintf("%9.f", 42.42) 242 | fmt.Sprintf("%.3g", 42.42) 243 | 244 | fmt.Sprintf("%b", float32(42.42)) 245 | fmt.Sprintf("%e", float32(42.42)) 246 | fmt.Sprintf("%E", float32(42.42)) 247 | fmt.Sprintf("%f", float32(42.42)) 248 | fmt.Sprintf("%F", float32(42.42)) 249 | fmt.Sprintf("%g", float32(42.42)) 250 | fmt.Sprintf("%G", float32(42.42)) 251 | fmt.Sprintf("%x", float32(42.42)) 252 | fmt.Sprintf("%X", float32(42.42)) 253 | fmt.Sprintf("%v", float32(42.42)) 254 | 255 | fmt.Sprintf("%b", 42.42) 256 | fmt.Sprintf("%e", 42.42) 257 | fmt.Sprintf("%E", 42.42) 258 | fmt.Sprintf("%f", 42.42) 259 | fmt.Sprintf("%F", 42.42) 260 | fmt.Sprintf("%g", 42.42) 261 | fmt.Sprintf("%G", 42.42) 262 | fmt.Sprintf("%x", 42.42) 263 | fmt.Sprintf("%X", 42.42) 264 | fmt.Sprintf("%v", 42.42) 265 | 266 | fmt.Sprintf("%b", 42i+42) 267 | fmt.Sprintf("%e", 42i+42) 268 | fmt.Sprintf("%E", 42i+42) 269 | fmt.Sprintf("%f", 42i+42) 270 | fmt.Sprintf("%F", 42i+42) 271 | fmt.Sprintf("%g", 42i+42) 272 | fmt.Sprintf("%G", 42i+42) 273 | fmt.Sprintf("%x", 42i+42) 274 | fmt.Sprintf("%X", 42i+42) 275 | fmt.Sprintf("%v", 42i+42) 276 | 277 | // String & slice of bytes. 278 | fmt.Sprintf("%q", "hello") 279 | fmt.Sprintf("%#q", `"hello"`) 280 | fmt.Sprintf("%+q", "hello") 281 | fmt.Sprintf("%X", "hello") 282 | 283 | // Slice. 284 | fmt.Sprintf("%x", []uint16{'d'}) 285 | fmt.Sprintf("%x", []uint32{'d'}) 286 | fmt.Sprintf("%x", []uint64{'d'}) 287 | fmt.Sprintf("%x", []uint{'d'}) 288 | fmt.Sprintf("%x", [1]byte{'c'}) 289 | fmt.Sprintf("%x", [1]uint8{'d'}) 290 | fmt.Sprintf("%x", [1]uint16{'d'}) 291 | fmt.Sprintf("%x", [1]uint32{'d'}) 292 | fmt.Sprintf("%x", [1]uint64{'d'}) 293 | fmt.Sprintf("%x", [1]uint{'d'}) 294 | fmt.Sprintf("%x", []int8{1}) 295 | fmt.Sprintf("%x", []int16{1}) 296 | fmt.Sprintf("%x", []int32{1}) 297 | fmt.Sprintf("%x", []int64{1}) 298 | fmt.Sprintf("%x", []int{1}) 299 | fmt.Sprintf("%x", [...]int8{1}) 300 | fmt.Sprintf("%x", [...]int16{1}) 301 | fmt.Sprintf("%x", [...]int32{1}) 302 | fmt.Sprintf("%x", [...]int64{1}) 303 | fmt.Sprintf("%x", [...]int{1}) 304 | fmt.Sprintf("%x", []string{"hello"}) 305 | fmt.Sprintf("%x", []rune{'a'}) 306 | 307 | fmt.Sprintf("% x", []byte{1, 2, 3}) 308 | fmt.Sprintf("% X", []byte{1, 2, 3}) 309 | fmt.Sprintf("%p", []byte{1, 2, 3}) 310 | fmt.Sprintf("%#p", []byte{1, 2, 3}) 311 | 312 | // Pointer. 313 | var ptr *int 314 | fmt.Sprintf("%v", ptr) 315 | fmt.Sprintf("%b", ptr) 316 | fmt.Sprintf("%d", ptr) 317 | fmt.Sprintf("%o", ptr) 318 | fmt.Sprintf("%x", ptr) 319 | fmt.Sprintf("%X", ptr) 320 | } 321 | 322 | func malformed() { 323 | fmt.Sprintf("%d", "example") 324 | fmt.Sprintf("%T", "example") 325 | fmt.Sprintf("%t", "example") 326 | fmt.Sprintf("%b", "example") 327 | fmt.Sprintf("%e", "example") 328 | fmt.Sprintf("%E", "example") 329 | fmt.Sprintf("%f", "example") 330 | fmt.Sprintf("%F", "example") 331 | fmt.Sprintf("%g", "example") 332 | fmt.Sprintf("%G", "example") 333 | fmt.Sprintf("%x", "example") 334 | fmt.Sprintf("%X", "example") 335 | 336 | fmt.Sprintf("%d", errSentinel) 337 | fmt.Sprintf("%T", errSentinel) 338 | fmt.Sprintf("%t", errSentinel) 339 | fmt.Sprintf("%b", errSentinel) 340 | fmt.Sprintf("%e", errSentinel) 341 | fmt.Sprintf("%E", errSentinel) 342 | fmt.Sprintf("%f", errSentinel) 343 | fmt.Sprintf("%F", errSentinel) 344 | fmt.Sprintf("%g", errSentinel) 345 | fmt.Sprintf("%G", errSentinel) 346 | fmt.Sprintf("%x", errSentinel) 347 | fmt.Sprintf("%X", errSentinel) 348 | 349 | fmt.Sprintf("%d", true) 350 | fmt.Sprintf("%T", true) 351 | fmt.Sprintf("%b", true) 352 | fmt.Sprintf("%e", true) 353 | fmt.Sprintf("%E", true) 354 | fmt.Sprintf("%f", true) 355 | fmt.Sprintf("%F", true) 356 | fmt.Sprintf("%g", true) 357 | fmt.Sprintf("%G", true) 358 | fmt.Sprintf("%x", true) 359 | fmt.Sprintf("%X", true) 360 | 361 | var bb []byte 362 | fmt.Sprintf("%d", bb) 363 | fmt.Sprintf("%T", bb) 364 | fmt.Sprintf("%t", bb) 365 | fmt.Sprintf("%b", bb) 366 | fmt.Sprintf("%e", bb) 367 | fmt.Sprintf("%E", bb) 368 | fmt.Sprintf("%f", bb) 369 | fmt.Sprintf("%F", bb) 370 | fmt.Sprintf("%g", bb) 371 | fmt.Sprintf("%G", bb) 372 | fmt.Sprintf("%X", bb) 373 | fmt.Sprintf("%v", bb) 374 | 375 | fmt.Sprintf("%T", 42) 376 | fmt.Sprintf("%t", 42) 377 | fmt.Sprintf("%b", 42) 378 | fmt.Sprintf("%e", 42) 379 | fmt.Sprintf("%E", 42) 380 | fmt.Sprintf("%f", 42) 381 | fmt.Sprintf("%F", 42) 382 | fmt.Sprintf("%g", 42) 383 | fmt.Sprintf("%G", 42) 384 | fmt.Sprintf("%x", 42) 385 | fmt.Sprintf("%X", 42) 386 | 387 | fmt.Sprintf("%T", uint(42)) 388 | fmt.Sprintf("%t", uint(42)) 389 | fmt.Sprintf("%b", uint(42)) 390 | fmt.Sprintf("%e", uint(42)) 391 | fmt.Sprintf("%E", uint(42)) 392 | fmt.Sprintf("%f", uint(42)) 393 | fmt.Sprintf("%F", uint(42)) 394 | fmt.Sprintf("%g", uint(42)) 395 | fmt.Sprintf("%G", uint(42)) 396 | fmt.Sprintf("%X", uint(42)) 397 | 398 | fmt.Sprintf("%d", 42.42) 399 | fmt.Sprintf("%d", map[string]string{}) 400 | fmt.Sprint(make(chan int)) 401 | fmt.Sprint([]int{1, 2, 3}) 402 | } 403 | -------------------------------------------------------------------------------- /analyzer/testdata/src/without-sprintf1/p.go: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | import ( // want "Fix imports" 4 | "errors" 5 | "fmt" 6 | "io" 7 | "log" 8 | "net/url" 9 | "os" 10 | "time" 11 | ) 12 | 13 | var errSentinel = errors.New("connection refused") 14 | 15 | func positive() { 16 | var s string 17 | fmt.Sprintf("%s", "hello") // want "string-format: fmt.Sprintf can be replaced with just using the string" 18 | fmt.Sprintf("%v", "hello") // want "string-format: fmt.Sprintf can be replaced with just using the string" 19 | fmt.Sprintf("hello") 20 | fmt.Sprint("hello") // want "string-format: fmt.Sprint can be replaced with just using the string" 21 | fmt.Sprintf("%s", s) // want "string-format: fmt.Sprintf can be replaced with just using the string" 22 | fmt.Sprintf("%[1]s", s) // want "string-format: fmt.Sprintf can be replaced with just using the string" 23 | fmt.Sprintf("%v", s) // want "string-format: fmt.Sprintf can be replaced with just using the string" 24 | fmt.Sprint(s) // want "string-format: fmt.Sprint can be replaced with just using the string" 25 | fmt.Errorf("hello") // want "error-format: fmt.Errorf can be replaced with errors.New" 26 | 27 | fmt.Sprintf("Hello %s", s) // want "string-format: fmt.Sprintf can be replaced with string concatenation" 28 | fmt.Sprintf("%s says Hello", s) // want "string-format: fmt.Sprintf can be replaced with string concatenation" 29 | fmt.Sprintf("Hello says %[1]s", s) // want "string-format: fmt.Sprintf can be replaced with string concatenation" 30 | 31 | var err error 32 | fmt.Sprintf("%s", errSentinel) 33 | fmt.Sprintf("%v", errSentinel) 34 | fmt.Sprint(errSentinel) 35 | fmt.Sprintf("%s", io.EOF) 36 | fmt.Sprintf("%v", io.EOF) 37 | fmt.Sprint(io.EOF) 38 | fmt.Sprintf("%s", err) 39 | fmt.Sprintf("%v", err) 40 | fmt.Sprint(err) 41 | 42 | var b bool 43 | fmt.Sprintf("%t", true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 44 | fmt.Sprintf("%v", true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 45 | fmt.Sprint(true) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 46 | fmt.Sprintf("%t", false) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 47 | fmt.Sprintf("%v", false) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 48 | fmt.Sprint(false) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 49 | fmt.Sprintf("%t", b) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 50 | fmt.Sprintf("%v", b) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 51 | fmt.Sprint(b) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 52 | 53 | var bs []byte 54 | var ba [3]byte 55 | fmt.Sprintf("%x", []byte{'a'}) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 56 | fmt.Sprintf("%x", []uint8{'b'}) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 57 | fmt.Sprintf("%x", bs) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 58 | fmt.Sprintf("%x", ba) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 59 | 60 | var i int 61 | var i8 int8 62 | var i16 int16 63 | var i32 int32 64 | var i64 int64 65 | fmt.Sprintf("%d", i) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 66 | fmt.Sprintf("%v", i) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 67 | fmt.Sprint(i) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 68 | fmt.Sprintf("%d", 42) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 69 | fmt.Sprintf("%v", 42) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 70 | fmt.Sprint(42) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 71 | fmt.Sprintf("%d", i8) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 72 | fmt.Sprintf("%v", i8) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 73 | fmt.Sprint(i8) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 74 | fmt.Sprintf("%d", int8(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 75 | fmt.Sprintf("%v", int8(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 76 | fmt.Sprint(int8(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 77 | fmt.Sprintf("%d", i16) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 78 | fmt.Sprintf("%v", i16) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 79 | fmt.Sprint(i16) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 80 | fmt.Sprintf("%d", int16(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 81 | fmt.Sprintf("%v", int16(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 82 | fmt.Sprint(int16(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 83 | fmt.Sprintf("%d", i32) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 84 | fmt.Sprintf("%v", i32) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 85 | fmt.Sprint(i32) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 86 | fmt.Sprintf("%d", int32(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 87 | fmt.Sprintf("%v", int32(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 88 | fmt.Sprint(int32(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 89 | fmt.Sprintf("%d", i64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 90 | fmt.Sprintf("%v", i64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 91 | fmt.Sprint(i64) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 92 | fmt.Sprintf("%d", int64(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 93 | fmt.Sprintf("%v", int64(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 94 | fmt.Sprint(int64(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 95 | 96 | var ui uint 97 | var ui8 uint8 98 | var ui16 uint16 99 | var ui32 uint32 100 | var ui64 uint64 101 | fmt.Sprintf("%d", ui) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 102 | fmt.Sprintf("%v", ui) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 103 | fmt.Sprint(ui) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 104 | fmt.Sprintf("%d", uint(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 105 | fmt.Sprintf("%v", uint(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 106 | fmt.Sprint(uint(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 107 | fmt.Sprintf("%d", ui8) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 108 | fmt.Sprintf("%v", ui8) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 109 | fmt.Sprint(ui8) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 110 | fmt.Sprintf("%d", uint8(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 111 | fmt.Sprintf("%v", uint8(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 112 | fmt.Sprint(uint8(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 113 | fmt.Sprintf("%d", ui16) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 114 | fmt.Sprintf("%v", ui16) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 115 | fmt.Sprint(ui16) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 116 | fmt.Sprintf("%d", uint16(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 117 | fmt.Sprintf("%v", uint16(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 118 | fmt.Sprint(uint16(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 119 | fmt.Sprintf("%d", ui32) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 120 | fmt.Sprintf("%v", ui32) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 121 | fmt.Sprint(ui32) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 122 | fmt.Sprintf("%d", uint32(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 123 | fmt.Sprintf("%v", uint32(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 124 | fmt.Sprint(uint32(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 125 | fmt.Sprintf("%d", ui64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 126 | fmt.Sprintf("%v", ui64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 127 | fmt.Sprintf("%x", ui64) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 128 | fmt.Sprintf("%x", uint(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 129 | fmt.Sprint(ui64) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 130 | fmt.Sprintf("%d", uint64(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 131 | fmt.Sprintf("%v", uint64(42)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 132 | fmt.Sprint(uint64(42)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 133 | } 134 | 135 | func suggestedFixesTest() { 136 | _ = func() string { 137 | if false { 138 | return fmt.Sprint("replace me") // want "string-format: fmt.Sprint can be replaced with just using the string" 139 | } 140 | return fmt.Sprintf("%s", "replace me") // want "string-format: fmt.Sprintf can be replaced with just using the string" 141 | } 142 | 143 | fmt.Println(fmt.Sprint(errSentinel)) 144 | fmt.Println(fmt.Sprintf("%s", errSentinel)) 145 | 146 | _ = func() string { 147 | switch 42 { 148 | case 1: 149 | return fmt.Sprint(false) // want "bool-format: fmt.Sprint can be replaced with faster strconv.FormatBool" 150 | case 2: 151 | return fmt.Sprintf("%t", true) // want "bool-format: fmt.Sprintf can be replaced with faster strconv.FormatBool" 152 | } 153 | return "" 154 | } 155 | 156 | var offset int 157 | params := url.Values{} 158 | params.Set("offset", fmt.Sprintf("%d", offset)) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.Itoa" 159 | params.Set("offset", fmt.Sprint(offset)) // want "integer-format: fmt.Sprint can be replaced with faster strconv.Itoa" 160 | 161 | var pubKey []byte 162 | if verifyPubKey := true; verifyPubKey { 163 | log.Println("pubkey=" + fmt.Sprintf("%x", pubKey)) // want "hex-format: fmt.Sprintf can be replaced with faster hex.EncodeToString" 164 | } 165 | 166 | var metaHash [16]byte 167 | fn := fmt.Sprintf("%s.%x", "coverage.MetaFilePref", metaHash) 168 | _ = "tmp." + fn + fmt.Sprintf("%d", time.Now().UnixNano()) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatInt" 169 | _ = "tmp." + fn + fmt.Sprint(time.Now().UnixNano()) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatInt" 170 | 171 | var change struct{ User struct{ ID uint } } 172 | var userStr string 173 | if id := change.User.ID; id != 0 { 174 | userStr = fmt.Sprintf("%d", id) // want "integer-format: fmt.Sprintf can be replaced with faster strconv.FormatUint" 175 | userStr = fmt.Sprint(id) // want "integer-format: fmt.Sprint can be replaced with faster strconv.FormatUint" 176 | } 177 | _ = userStr 178 | } 179 | 180 | func negative() { 181 | const val = "val%d" 182 | 183 | _ = int32(42) 184 | 185 | fmt.Scan(42) 186 | fmt.Scanf("%d", 42) 187 | fmt.Println("%d", 42) 188 | fmt.Printf("%d") 189 | fmt.Printf("%v") 190 | fmt.Printf("%d", 42) 191 | fmt.Printf("%s %d", "hello", 42) 192 | fmt.Errorf("this is %s", "complex") 193 | 194 | fmt.Fprint(os.Stdout, "%d", 42) 195 | fmt.Fprintf(os.Stdout, "test") 196 | fmt.Fprintf(os.Stdout, "%d") 197 | fmt.Fprintf(os.Stdout, "%v") 198 | fmt.Fprintf(os.Stdout, "%d", 42) 199 | fmt.Fprintf(os.Stdout, "%s %d", "hello", 42) 200 | 201 | fmt.Sprint("test", 42) 202 | fmt.Sprint(42, 42) 203 | fmt.Sprintf("%d", 42, 42) 204 | fmt.Sprintf("%#d", 42) 205 | fmt.Sprintf("value %d", 42) 206 | fmt.Sprintf(val, 42) 207 | fmt.Sprintf("%s %v", "hello", "world") 208 | fmt.Sprintf("%#v", 42) 209 | fmt.Sprintf("%T", struct{ string }{}) 210 | fmt.Sprintf("%%v", 42) 211 | fmt.Sprintf("%3d", 42) 212 | fmt.Sprintf("% d", 42) 213 | fmt.Sprintf("%-10d", 42) 214 | fmt.Sprintf("%s %[1]s", "hello") 215 | fmt.Sprintf("%[1]s %[1]s", "hello") 216 | fmt.Sprintf("%[2]d %[1]d\n", 11, 22) 217 | fmt.Sprintf("%[3]*.[2]*[1]f", 12.0, 2, 6) 218 | fmt.Sprintf("%d %d %#[1]x %#x", 16, 17) 219 | 220 | // Integer. 221 | fmt.Sprintf("%#x", uint64(42)) 222 | fmt.Sprintf("%#v", uint64(42)) 223 | fmt.Sprintf("%#b", 42) 224 | fmt.Sprintf("%#o", 42) 225 | fmt.Sprintf("%#x", 42) 226 | fmt.Sprintf("%#X", 42) 227 | 228 | fmt.Sprintf("%b", 42) 229 | fmt.Sprintf("%c", 42) 230 | fmt.Sprintf("%o", 42) 231 | fmt.Sprintf("%O", 42) 232 | fmt.Sprintf("%q", 42) 233 | fmt.Sprintf("%x", 42) 234 | fmt.Sprintf("%X", 42) 235 | 236 | // Floating point. 237 | fmt.Sprintf("%9f", 42.42) 238 | fmt.Sprintf("%.2f", 42.42) 239 | fmt.Sprintf("%.2f", 42.42) 240 | fmt.Sprintf("%9.2f", 42.42) 241 | fmt.Sprintf("%9.f", 42.42) 242 | fmt.Sprintf("%.3g", 42.42) 243 | 244 | fmt.Sprintf("%b", float32(42.42)) 245 | fmt.Sprintf("%e", float32(42.42)) 246 | fmt.Sprintf("%E", float32(42.42)) 247 | fmt.Sprintf("%f", float32(42.42)) 248 | fmt.Sprintf("%F", float32(42.42)) 249 | fmt.Sprintf("%g", float32(42.42)) 250 | fmt.Sprintf("%G", float32(42.42)) 251 | fmt.Sprintf("%x", float32(42.42)) 252 | fmt.Sprintf("%X", float32(42.42)) 253 | fmt.Sprintf("%v", float32(42.42)) 254 | 255 | fmt.Sprintf("%b", 42.42) 256 | fmt.Sprintf("%e", 42.42) 257 | fmt.Sprintf("%E", 42.42) 258 | fmt.Sprintf("%f", 42.42) 259 | fmt.Sprintf("%F", 42.42) 260 | fmt.Sprintf("%g", 42.42) 261 | fmt.Sprintf("%G", 42.42) 262 | fmt.Sprintf("%x", 42.42) 263 | fmt.Sprintf("%X", 42.42) 264 | fmt.Sprintf("%v", 42.42) 265 | 266 | fmt.Sprintf("%b", 42i+42) 267 | fmt.Sprintf("%e", 42i+42) 268 | fmt.Sprintf("%E", 42i+42) 269 | fmt.Sprintf("%f", 42i+42) 270 | fmt.Sprintf("%F", 42i+42) 271 | fmt.Sprintf("%g", 42i+42) 272 | fmt.Sprintf("%G", 42i+42) 273 | fmt.Sprintf("%x", 42i+42) 274 | fmt.Sprintf("%X", 42i+42) 275 | fmt.Sprintf("%v", 42i+42) 276 | 277 | // String & slice of bytes. 278 | fmt.Sprintf("%q", "hello") 279 | fmt.Sprintf("%#q", `"hello"`) 280 | fmt.Sprintf("%+q", "hello") 281 | fmt.Sprintf("%X", "hello") 282 | 283 | // Slice. 284 | fmt.Sprintf("%x", []uint16{'d'}) 285 | fmt.Sprintf("%x", []uint32{'d'}) 286 | fmt.Sprintf("%x", []uint64{'d'}) 287 | fmt.Sprintf("%x", []uint{'d'}) 288 | fmt.Sprintf("%x", [1]byte{'c'}) 289 | fmt.Sprintf("%x", [1]uint8{'d'}) 290 | fmt.Sprintf("%x", [1]uint16{'d'}) 291 | fmt.Sprintf("%x", [1]uint32{'d'}) 292 | fmt.Sprintf("%x", [1]uint64{'d'}) 293 | fmt.Sprintf("%x", [1]uint{'d'}) 294 | fmt.Sprintf("%x", []int8{1}) 295 | fmt.Sprintf("%x", []int16{1}) 296 | fmt.Sprintf("%x", []int32{1}) 297 | fmt.Sprintf("%x", []int64{1}) 298 | fmt.Sprintf("%x", []int{1}) 299 | fmt.Sprintf("%x", [...]int8{1}) 300 | fmt.Sprintf("%x", [...]int16{1}) 301 | fmt.Sprintf("%x", [...]int32{1}) 302 | fmt.Sprintf("%x", [...]int64{1}) 303 | fmt.Sprintf("%x", [...]int{1}) 304 | fmt.Sprintf("%x", []string{"hello"}) 305 | fmt.Sprintf("%x", []rune{'a'}) 306 | 307 | fmt.Sprintf("% x", []byte{1, 2, 3}) 308 | fmt.Sprintf("% X", []byte{1, 2, 3}) 309 | fmt.Sprintf("%p", []byte{1, 2, 3}) 310 | fmt.Sprintf("%#p", []byte{1, 2, 3}) 311 | 312 | // Pointer. 313 | var ptr *int 314 | fmt.Sprintf("%v", ptr) 315 | fmt.Sprintf("%b", ptr) 316 | fmt.Sprintf("%d", ptr) 317 | fmt.Sprintf("%o", ptr) 318 | fmt.Sprintf("%x", ptr) 319 | fmt.Sprintf("%X", ptr) 320 | } 321 | 322 | func malformed() { 323 | fmt.Sprintf("%d", "example") 324 | fmt.Sprintf("%T", "example") 325 | fmt.Sprintf("%t", "example") 326 | fmt.Sprintf("%b", "example") 327 | fmt.Sprintf("%e", "example") 328 | fmt.Sprintf("%E", "example") 329 | fmt.Sprintf("%f", "example") 330 | fmt.Sprintf("%F", "example") 331 | fmt.Sprintf("%g", "example") 332 | fmt.Sprintf("%G", "example") 333 | fmt.Sprintf("%x", "example") 334 | fmt.Sprintf("%X", "example") 335 | 336 | fmt.Sprintf("%d", errSentinel) 337 | fmt.Sprintf("%T", errSentinel) 338 | fmt.Sprintf("%t", errSentinel) 339 | fmt.Sprintf("%b", errSentinel) 340 | fmt.Sprintf("%e", errSentinel) 341 | fmt.Sprintf("%E", errSentinel) 342 | fmt.Sprintf("%f", errSentinel) 343 | fmt.Sprintf("%F", errSentinel) 344 | fmt.Sprintf("%g", errSentinel) 345 | fmt.Sprintf("%G", errSentinel) 346 | fmt.Sprintf("%x", errSentinel) 347 | fmt.Sprintf("%X", errSentinel) 348 | 349 | fmt.Sprintf("%d", true) 350 | fmt.Sprintf("%T", true) 351 | fmt.Sprintf("%b", true) 352 | fmt.Sprintf("%e", true) 353 | fmt.Sprintf("%E", true) 354 | fmt.Sprintf("%f", true) 355 | fmt.Sprintf("%F", true) 356 | fmt.Sprintf("%g", true) 357 | fmt.Sprintf("%G", true) 358 | fmt.Sprintf("%x", true) 359 | fmt.Sprintf("%X", true) 360 | 361 | var bb []byte 362 | fmt.Sprintf("%d", bb) 363 | fmt.Sprintf("%T", bb) 364 | fmt.Sprintf("%t", bb) 365 | fmt.Sprintf("%b", bb) 366 | fmt.Sprintf("%e", bb) 367 | fmt.Sprintf("%E", bb) 368 | fmt.Sprintf("%f", bb) 369 | fmt.Sprintf("%F", bb) 370 | fmt.Sprintf("%g", bb) 371 | fmt.Sprintf("%G", bb) 372 | fmt.Sprintf("%X", bb) 373 | fmt.Sprintf("%v", bb) 374 | 375 | fmt.Sprintf("%T", 42) 376 | fmt.Sprintf("%t", 42) 377 | fmt.Sprintf("%b", 42) 378 | fmt.Sprintf("%e", 42) 379 | fmt.Sprintf("%E", 42) 380 | fmt.Sprintf("%f", 42) 381 | fmt.Sprintf("%F", 42) 382 | fmt.Sprintf("%g", 42) 383 | fmt.Sprintf("%G", 42) 384 | fmt.Sprintf("%x", 42) 385 | fmt.Sprintf("%X", 42) 386 | 387 | fmt.Sprintf("%T", uint(42)) 388 | fmt.Sprintf("%t", uint(42)) 389 | fmt.Sprintf("%b", uint(42)) 390 | fmt.Sprintf("%e", uint(42)) 391 | fmt.Sprintf("%E", uint(42)) 392 | fmt.Sprintf("%f", uint(42)) 393 | fmt.Sprintf("%F", uint(42)) 394 | fmt.Sprintf("%g", uint(42)) 395 | fmt.Sprintf("%G", uint(42)) 396 | fmt.Sprintf("%X", uint(42)) 397 | 398 | fmt.Sprintf("%d", 42.42) 399 | fmt.Sprintf("%d", map[string]string{}) 400 | fmt.Sprint(make(chan int)) 401 | fmt.Sprint([]int{1, 2, 3}) 402 | } 403 | --------------------------------------------------------------------------------