{"id":20820364,"url":"https://github.com/kyoh86/looppointer","last_synced_at":"2025-05-07T15:44:06.711Z","repository":{"id":39877167,"uuid":"249216721","full_name":"kyoh86/looppointer","owner":"kyoh86","description":"An analyzer that checks for pointers to enclosing loop variables.","archived":false,"fork":false,"pushed_at":"2023-11-13T16:49:56.000Z","size":59,"stargazers_count":38,"open_issues_count":3,"forks_count":4,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-06-18T18:46:16.354Z","etag":null,"topics":["diagnostics","go","golang","linter"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kyoh86.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-03-22T15:48:47.000Z","updated_at":"2024-02-22T10:10:46.000Z","dependencies_parsed_at":"2023-11-13T17:54:32.644Z","dependency_job_id":null,"html_url":"https://github.com/kyoh86/looppointer","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kyoh86%2Flooppointer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kyoh86%2Flooppointer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kyoh86%2Flooppointer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kyoh86%2Flooppointer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kyoh86","download_url":"https://codeload.github.com/kyoh86/looppointer/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225096700,"owners_count":17420293,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["diagnostics","go","golang","linter"],"created_at":"2024-11-17T22:09:02.060Z","updated_at":"2024-11-17T22:09:02.536Z","avatar_url":"https://github.com/kyoh86.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# looppointer\n\nAn analyzer that finds pointers for loop variables.\n\n[![PkgGoDev](https://pkg.go.dev/badge/kyoh86/looppointer)](https://pkg.go.dev/kyoh86/looppointer)\n[![Go Report Card](https://goreportcard.com/badge/github.com/kyoh86/looppointer)](https://goreportcard.com/report/github.com/kyoh86/looppointer)\n[![Coverage Status](https://img.shields.io/codecov/c/github/kyoh86/looppointer.svg)](https://codecov.io/gh/kyoh86/looppointer)\n[![Release](https://github.com/kyoh86/looppointer/workflows/Release/badge.svg)](https://github.com/kyoh86/looppointer/releases)\n\n## What's this?\n\nSample problem code from: https://github.com/kyoh86/looppointer/blob/main/testdata/simple/simple.go\n\n```go\npackage main\n\nfunc main() {\n\tvar intSlice []*int\n\n\tprintln(\"loop expecting 10, 11, 12, 13\")\n\tfor _, p := range []int{10, 11, 12, 13} {\n\t\tintSlice = append(intSlice, \u0026p) // want \"taking a pointer for the loop variable p\"\n\t}\n\n\tprintln(`slice expecting \"10, 11, 12, 13\" but \"13, 13, 13, 13\"`)\n\tfor _, p := range intSlice {\n\t\tprintp(p)\n\t}\n}\n\nfunc printp(p *int) {\n\tprintln(*p)\n}\n```\n\nIn Go, the `p` variable in the above loops is actually a single variable.\nSo in many case (like the above), using it makes for us annoying bugs.\n\nYou can find them with `looppointer`, and fix it.\n\n```go\npackage main\n\nfunc main() {\n\tvar intSlice []*int\n\n\tprintln(\"loop expecting 10, 11, 12, 13\")\n\tfor i, p := range []int{10, 11, 12, 13} {\n    p := p                          // FIX variable into the local variable\n\t\tintSlice = append(intSlice, \u0026p) \n\t}\n\n\tprintln(`slice expecting \"10, 11, 12, 13\"`)\n\tfor _, p := range intSlice {\n\t\tprintp(p)\n\t}\n}\n\nfunc printp(p *int) {\n\tprintln(*p)\n}\n```\n\nref: https://github.com/kyoh86/looppointer/blob/main/testdata/fixed/fixed.go\n\n## Sensing policy\n\nI want to make looppointer as nervous as possible.\nSo some false-positves will be reported.\n\ne.g.\n\n```go\nfunc TestSample(t *testing.T) {\n  for _, p := []int{10, 11, 12, 13} {\n    t.Run(func(t *testing.T) {\n      s = \u0026p // t.Run always called instantly, so it will not be bug.\n      ...\n    })\n  }\n}\n```\n\nThey can be escaped with pining-variable:\n\n```go\nfunc TestSample(t *testing.T) {\n  for _, p := []int{10, 11, 12, 13} {\n    p := p // pin a variable to local in the loop\n    t.Run(func(t *testing.T) {\n      s = \u0026p\n      ...\n    })\n  }\n}\n```\n\nIf you want to ignore false-positives (with some lints ignored),\nyou should use [exportloopref](https://github.com/kyoh86/exportloopref).\n\n## Nolint\n\nDiagnostics by `looppointer` can be suppress with the line comment `// nolint:looppointer`.\n\n```go\nfunc TestSample(t *testing.T) {\n  for _, p := []int{10, 11, 12, 13} {\n    t.Run(func(t *testing.T) {\n      s = \u0026p // nolint\n      ...\n    })\n  }\n}\n```\n\n\n## Install\n\ngo:\n\n```console\n$ go install github.com/kyoh86/looppointer/cmd/looppointer@latest\n```\n\n[homebrew](https://brew.sh/):\n\n```console\n$ brew install kyoh86/tap/looppointer\n```\n\n[gordon](https://github.com/kyoh86/gordon):\n\n```console\n$ gordon install kyoh86/looppointer\n```\n\n## Usage\n\n```\nlooppointer [-flag] [package]\n```\n\n### Flags\n\n| Flag | Description |\n| --- | --- |\n| -V                 | print version and exit |\n| -all               | no effect (deprecated) |\n| -c int             | display offending line with this many lines of context (default -1) |\n| -cpuprofile string | write CPU profile to this file |\n| -debug string      | debug flags, any subset of \"fpstv\" |\n| -fix               | apply all suggested fixes |\n| -flags             | print analyzer flags in JSON |\n| -json              | emit JSON output |\n| -memprofile string | write memory profile to this file |\n| -source            | no effect (deprecated) |\n| -tags string       | no effect (deprecated) |\n| -trace string      | write trace log to this file |\n| -v                 | no effect (deprecated) |\n\n# LICENSE\n\n[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg)](http://www.opensource.org/licenses/MIT)\n\nThis is distributed under the [MIT License](http://www.opensource.org/licenses/MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkyoh86%2Flooppointer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkyoh86%2Flooppointer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkyoh86%2Flooppointer/lists"}