All Projects → kyoh86 → looppointer

kyoh86 / looppointer

Licence: MIT license
An analyzer that checks for pointers to enclosing loop variables.

Programming Languages

go
31211 projects - #10 most used programming language
Makefile
30231 projects

Projects that are alternatives of or similar to looppointer

codeclimate-apexmetrics
ApexMetrics - Code Climate engine for Salesforce [DISCONTINUED use CC PMD instead)
Stars: ✭ 46 (+53.33%)
Mutual labels:  linter
clang-format-action
GitHub Action for clang-format checking
Stars: ✭ 48 (+60%)
Mutual labels:  linter
EditorConfig-Action
🔎A GitHub Action to check, enforce & fix EditorConfig style violations
Stars: ✭ 40 (+33.33%)
Mutual labels:  linter
errchkjson
Go linter that checks types that are json encoded - reports unsupported types and unnecessary error checks
Stars: ✭ 29 (-3.33%)
Mutual labels:  linter
virtool
Viral infection diagnostics using next-generation sequencing
Stars: ✭ 36 (+20%)
Mutual labels:  diagnostics
dlint
Dlint is a tool for encouraging best coding practices and helping ensure Python code is secure.
Stars: ✭ 130 (+333.33%)
Mutual labels:  linter
yakut
Simple CLI tool for diagnostics and debugging of Cyphal networks
Stars: ✭ 29 (-3.33%)
Mutual labels:  diagnostics
jsish
Jsi is a small, C-embeddable javascript interpreter with tightly woven Web and DB support.
Stars: ✭ 32 (+6.67%)
Mutual labels:  diagnostics
peon
Python "Elegant Object" Naive linter.
Stars: ✭ 31 (+3.33%)
Mutual labels:  linter
flycheck-joker
Clojure syntax checker (via Joker) for flycheck
Stars: ✭ 55 (+83.33%)
Mutual labels:  linter
kaltura-device-info-android
Kaltura Device Info
Stars: ✭ 26 (-13.33%)
Mutual labels:  diagnostics
vnu-elixir
An Elixir client for the Nu HTML Checker (v.Nu).
Stars: ✭ 50 (+66.67%)
Mutual labels:  linter
lints
Lint all your JavaScript, CSS, HTML, Markdown and Dockerfiles with a single command
Stars: ✭ 14 (-53.33%)
Mutual labels:  linter
sqlclosecheck
Linter that confirms that DB rows and stats are closed properly.
Stars: ✭ 21 (-30%)
Mutual labels:  linter
syntastic-extras
Additional Syntastic syntax checkers and features (for Vim)
Stars: ✭ 31 (+3.33%)
Mutual labels:  linter
actionlint
Static checker for GitHub Actions workflow files
Stars: ✭ 1,385 (+4516.67%)
Mutual labels:  linter
bun
DC/OS diagnostics bundle analysis tool
Stars: ✭ 13 (-56.67%)
Mutual labels:  diagnostics
go-perfguard
CPU-guided performance analyzer for Go
Stars: ✭ 58 (+93.33%)
Mutual labels:  linter
ramllint
RAML Linter
Stars: ✭ 18 (-40%)
Mutual labels:  linter
gsc
Go Source Checker
Stars: ✭ 15 (-50%)
Mutual labels:  linter

looppointer

An analyzer that finds pointers for loop variables.

PkgGoDev Go Report Card Coverage Status Release

What's this?

Sample problem code from: https://github.com/kyoh86/looppointer/blob/main/testdata/simple/simple.go

package main

func main() {
	var intSlice []*int

	println("loop expecting 10, 11, 12, 13")
	for _, p := range []int{10, 11, 12, 13} {
		intSlice = append(intSlice, &p) // want "taking a pointer for the loop variable p"
	}

	println(`slice expecting "10, 11, 12, 13" but "13, 13, 13, 13"`)
	for _, p := range intSlice {
		printp(p)
	}
}

func printp(p *int) {
	println(*p)
}

In Go, the p variable in the above loops is actually a single variable. So in many case (like the above), using it makes for us annoying bugs.

You can find them with looppointer, and fix it.

package main

func main() {
	var intSlice []*int

	println("loop expecting 10, 11, 12, 13")
	for i, p := range []int{10, 11, 12, 13} {
    p := p                          // FIX variable into the local variable
		intSlice = append(intSlice, &p) 
	}

	println(`slice expecting "10, 11, 12, 13"`)
	for _, p := range intSlice {
		printp(p)
	}
}

func printp(p *int) {
	println(*p)
}

ref: https://github.com/kyoh86/looppointer/blob/main/testdata/fixed/fixed.go

Sensing policy

I want to make looppointer as nervous as possible. So some false-positves will be reported.

e.g.

func TestSample(t *testing.T) {
  for _, p := []int{10, 11, 12, 13} {
    t.Run(func(t *testing.T) {
      s = &p // t.Run always called instantly, so it will not be bug.
      ...
    })
  }
}

They can be escaped with pining-variable:

func TestSample(t *testing.T) {
  for _, p := []int{10, 11, 12, 13} {
    p := p // pin a variable to local in the loop
    t.Run(func(t *testing.T) {
      s = &p
      ...
    })
  }
}

If you want to ignore false-positives (with some lints ignored), you should use exportloopref.

Nolint

Diagnostics by looppointer can be suppress with the line comment // nolint:looppointer.

func TestSample(t *testing.T) {
  for _, p := []int{10, 11, 12, 13} {
    t.Run(func(t *testing.T) {
      s = &p // nolint
      ...
    })
  }
}

Install

go:

$ go get github.com/kyoh86/looppointer/cmd/looppointer

homebrew:

$ brew install kyoh86/tap/looppointer

gordon:

$ gordon install kyoh86/looppointer

Usage

looppointer [-flag] [package]

Flags

Flag Description
-V print version and exit
-all no effect (deprecated)
-c int display offending line with this many lines of context (default -1)
-cpuprofile string write CPU profile to this file
-debug string debug flags, any subset of "fpstv"
-fix apply all suggested fixes
-flags print analyzer flags in JSON
-json emit JSON output
-memprofile string write memory profile to this file
-source no effect (deprecated)
-tags string no effect (deprecated)
-trace string write trace log to this file
-v no effect (deprecated)

LICENSE

MIT License

This is distributed under the MIT License.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].