aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/kyoh86
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2021-02-22 20:37:25 +0100
committerDmitry Vyukov <dvyukov@google.com>2021-02-22 21:02:12 +0100
commitfcc6d71be2c3ce7d9305c04fc2e87af554571bac (patch)
treeb01dbb3d1e2988e28ea158d2d543d603ec0b9569 /vendor/github.com/kyoh86
parent8f23c528ad5a943b9ffec5dcaf332fd0f614006e (diff)
go.mod: update golangci-lint to v1.37
Diffstat (limited to 'vendor/github.com/kyoh86')
-rw-r--r--vendor/github.com/kyoh86/exportloopref/.golangci.yml2
-rw-r--r--vendor/github.com/kyoh86/exportloopref/README.md55
-rw-r--r--vendor/github.com/kyoh86/exportloopref/exportloopref.go83
-rw-r--r--vendor/github.com/kyoh86/exportloopref/go.mod2
-rw-r--r--vendor/github.com/kyoh86/exportloopref/go.sum6
5 files changed, 110 insertions, 38 deletions
diff --git a/vendor/github.com/kyoh86/exportloopref/.golangci.yml b/vendor/github.com/kyoh86/exportloopref/.golangci.yml
index 58667b215..e876057f3 100644
--- a/vendor/github.com/kyoh86/exportloopref/.golangci.yml
+++ b/vendor/github.com/kyoh86/exportloopref/.golangci.yml
@@ -1,4 +1,4 @@
linters:
enable:
- unparam
- - scopelint
+ - exportloopref
diff --git a/vendor/github.com/kyoh86/exportloopref/README.md b/vendor/github.com/kyoh86/exportloopref/README.md
index 5b1549159..5c019c738 100644
--- a/vendor/github.com/kyoh86/exportloopref/README.md
+++ b/vendor/github.com/kyoh86/exportloopref/README.md
@@ -2,13 +2,14 @@
An analyzer that finds exporting pointers for loop variables.
+[![PkgGoDev](https://pkg.go.dev/badge/kyoh86/exportloopref)](https://pkg.go.dev/kyoh86/exportloopref)
[![Go Report Card](https://goreportcard.com/badge/github.com/kyoh86/exportloopref)](https://goreportcard.com/report/github.com/kyoh86/exportloopref)
[![Coverage Status](https://img.shields.io/codecov/c/github/kyoh86/exportloopref.svg)](https://codecov.io/gh/kyoh86/exportloopref)
[![Release](https://github.com/kyoh86/exportloopref/workflows/Release/badge.svg)](https://github.com/kyoh86/exportloopref/releases)
## What's this?
-Sample problem code from: https://github.com/kyoh86/exportloopref/blob/master/testdata/simple/simple.go
+Sample problem code from: https://github.com/kyoh86/exportloopref/blob/master/testdata/src/simple/simple.go
```go
package main
@@ -32,8 +33,8 @@ func main() {
var vArray [4]*int
var v *int
if i%2 == 0 {
- v = &p // not a diagnostic (x is inner variable)
- vArray[1] = &p // not a diagnostic (x is inner variable)
+ v = &p // not a diagnostic (x is local variable)
+ vArray[1] = &p // not a diagnostic (x is local variable)
vStr.x = &p
}
_ = v
@@ -72,7 +73,7 @@ func main() {
println("loop expecting 10, 11, 12, 13")
for i, p := range []int{10, 11, 12, 13} {
- p := p // FIX variable into the inner variable
+ p := p // FIX variable into the local variable
printp(&p)
intSlice = append(intSlice, &p)
intArray[i] = &p
@@ -108,12 +109,12 @@ func printp(p *int) {
}
```
-ref: https://github.com/kyoh86/exportloopref/blob/master/testdata/fixed/fixed.go
+ref: https://github.com/kyoh86/exportloopref/blob/master/testdata/src/fixed/fixed.go
## Sensing policy
I want to make exportloopref as accurately as possible.
-So some cases of lints will be ignored.
+So some cases of lints will be false-negative.
e.g.
@@ -127,6 +128,48 @@ for _, p := []int{10, 11, 12, 13} {
If you want to report all of lints (with some false-positives),
you should use [looppointer](https://github.com/kyoh86/looppointer).
+### Known false negatives
+
+Case 1: pass the pointer to function to export.
+
+Case 2: pass the pointer to local variable, and export it.
+
+```go
+package main
+
+type List []*int
+
+func (l *List) AppendP(p *int) {
+ *l = append(*l, p)
+}
+
+func main() {
+ var slice []*int
+ list := List{}
+
+ println("loop expect exporting 10, 11, 12, 13")
+ for _, v := range []int{10, 11, 12, 13} {
+ list.AppendP(&v) // Case 1: wanted "exporting a pointer for the loop variable v", but cannot be found
+
+ p := &v // p is the local variable
+ slice = append(slice, p) // Case 2: wanted "exporting a pointer for the loop variable v", but cannot be found
+ }
+
+ println(`slice expecting "10, 11, 12, 13" but "13, 13, 13, 13"`)
+ for _, p := range slice {
+ printp(p)
+ }
+ println(`array expecting "10, 11, 12, 13" but "13, 13, 13, 13"`)
+ for _, p := range ([]*int)(list) {
+ printp(p)
+ }
+}
+
+func printp(p *int) {
+ println(*p)
+}
+```
+
## Install
go:
diff --git a/vendor/github.com/kyoh86/exportloopref/exportloopref.go b/vendor/github.com/kyoh86/exportloopref/exportloopref.go
index 0b310b3c9..4d1671a06 100644
--- a/vendor/github.com/kyoh86/exportloopref/exportloopref.go
+++ b/vendor/github.com/kyoh86/exportloopref/exportloopref.go
@@ -1,6 +1,7 @@
package exportloopref
import (
+ "fmt"
"go/ast"
"go/token"
"go/types"
@@ -42,9 +43,28 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
inspect.WithStack(nodeFilter, func(n ast.Node, push bool, stack []ast.Node) bool {
- id, digg := search.Check(n, stack)
+ id, insert, digg := search.Check(n, stack)
if id != nil {
- pass.ReportRangef(id, "exporting a pointer for the loop variable %s", id.Name)
+ dMsg := fmt.Sprintf("exporting a pointer for the loop variable %s", id.Name)
+ fMsg := fmt.Sprintf("loop variable %s should be pinned", id.Name)
+ var suggest []analysis.SuggestedFix
+ if insert != token.NoPos {
+ suggest = []analysis.SuggestedFix{{
+ Message: fMsg,
+ TextEdits: []analysis.TextEdit{{
+ Pos: insert,
+ End: insert,
+ NewText: []byte(fmt.Sprintf("%[1]s := %[1]s\n", id.Name)),
+ }},
+ }}
+ }
+ d := analysis.Diagnostic{Pos: id.Pos(),
+ End: id.End(),
+ Message: dMsg,
+ Category: "exportloopref",
+ SuggestedFixes: suggest,
+ }
+ pass.Report(d)
}
return digg
})
@@ -59,13 +79,13 @@ type Searcher struct {
// - var <X> int
// - D := ...
Stats map[token.Pos]struct{}
- // Internal variables maps loop-position, decl-location to ignore
+ // Local variables maps loop-position, decl-location to ignore
// safe pointers for variable which declared in the loop.
Vars map[token.Pos]map[token.Pos]struct{}
Types map[ast.Expr]types.TypeAndValue
}
-func (s *Searcher) Check(n ast.Node, stack []ast.Node) (*ast.Ident, bool) {
+func (s *Searcher) Check(n ast.Node, stack []ast.Node) (*ast.Ident, token.Pos, bool) {
switch typed := n.(type) {
case *ast.RangeStmt:
s.parseRangeStmt(typed)
@@ -79,7 +99,7 @@ func (s *Searcher) Check(n ast.Node, stack []ast.Node) (*ast.Ident, bool) {
case *ast.UnaryExpr:
return s.checkUnaryExpr(typed, stack)
}
- return nil, true
+ return nil, token.NoPos, true
}
func (s *Searcher) parseRangeStmt(n *ast.RangeStmt) {
@@ -107,7 +127,7 @@ func (s *Searcher) addStat(expr ast.Expr) {
}
func (s *Searcher) parseDeclStmt(n *ast.DeclStmt, stack []ast.Node) {
- loop := s.innermostLoop(stack)
+ loop, _ := s.innermostLoop(stack)
if loop == nil {
return
}
@@ -123,12 +143,12 @@ func (s *Searcher) parseDeclStmt(n *ast.DeclStmt, stack []ast.Node) {
}
func (s *Searcher) parseAssignStmt(n *ast.AssignStmt, stack []ast.Node) {
- loop := s.innermostLoop(stack)
+ loop, _ := s.innermostLoop(stack)
if loop == nil {
return
}
- // Find statements declaring internal variable
+ // Find statements declaring local variable
if n.Tok == token.DEFINE {
for _, h := range n.Lhs {
s.addVar(loop, h)
@@ -150,36 +170,45 @@ func (s *Searcher) addVar(loop ast.Node, expr ast.Expr) {
s.Vars[loopPos] = vars
}
-func (s *Searcher) innermostLoop(stack []ast.Node) ast.Node {
+func insertionPosition(block *ast.BlockStmt) token.Pos {
+ if len(block.List) > 0 {
+ return block.List[0].Pos()
+ }
+ return token.NoPos
+}
+
+func (s *Searcher) innermostLoop(stack []ast.Node) (ast.Node, token.Pos) {
for i := len(stack) - 1; i >= 0; i-- {
- switch stack[i].(type) {
- case *ast.RangeStmt, *ast.ForStmt:
- return stack[i]
+ switch typed := stack[i].(type) {
+ case *ast.RangeStmt:
+ return typed, insertionPosition(typed.Body)
+ case *ast.ForStmt:
+ return typed, insertionPosition(typed.Body)
}
}
- return nil
+ return nil, token.NoPos
}
-func (s *Searcher) checkUnaryExpr(n *ast.UnaryExpr, stack []ast.Node) (*ast.Ident, bool) {
- loop := s.innermostLoop(stack)
+func (s *Searcher) checkUnaryExpr(n *ast.UnaryExpr, stack []ast.Node) (*ast.Ident, token.Pos, bool) {
+ loop, insert := s.innermostLoop(stack)
if loop == nil {
- return nil, true
+ return nil, token.NoPos, true
}
if n.Op != token.AND {
- return nil, true
+ return nil, token.NoPos, true
}
// Get identity of the referred item
id := s.getIdentity(n.X)
if id == nil {
- return nil, true
+ return nil, token.NoPos, true
}
// If the identity is not the loop statement variable,
// it will not be reported.
if _, isStat := s.Stats[id.Obj.Pos()]; !isStat {
- return nil, true
+ return nil, token.NoPos, true
}
// check stack append(), []X{}, map[Type]X{}, Struct{}, &Struct{}, X.(Type), (X)
@@ -196,16 +225,16 @@ func (s *Searcher) checkUnaryExpr(n *ast.UnaryExpr, stack []ast.Node) (*ast.Iden
case (*ast.CallExpr):
fun, ok := typed.Fun.(*ast.Ident)
if !ok {
- return nil, false // it's calling a function other of `append`. It cannot be checked
+ return nil, token.NoPos, false // it's calling a function other of `append`. It cannot be checked
}
if fun.Name != "append" {
- return nil, false // it's calling a function other of `append`. It cannot be checked
+ return nil, token.NoPos, false // it's calling a function other of `append`. It cannot be checked
}
case (*ast.AssignStmt):
if len(typed.Rhs) != len(typed.Lhs) {
- return nil, false // dead logic
+ return nil, token.NoPos, false // dead logic
}
// search x where Rhs[x].Pos() == mayRHPos
@@ -217,23 +246,23 @@ func (s *Searcher) checkUnaryExpr(n *ast.UnaryExpr, stack []ast.Node) (*ast.Iden
}
}
- // check Lhs[x] is not inner variable
+ // check Lhs[x] is not local variable
lh := typed.Lhs[index]
isVar := s.isVar(loop, lh)
if !isVar {
- return id, false
+ return id, insert, false
}
- return nil, true
+ return nil, token.NoPos, true
default:
// Other statement is not able to be checked.
- return nil, false
+ return nil, token.NoPos, false
}
// memory an expr that may be right-hand in the AssignStmt
mayRHPos = stack[i].Pos()
}
- return nil, true
+ return nil, token.NoPos, true
}
func (s *Searcher) isVar(loop ast.Node, expr ast.Expr) bool {
diff --git a/vendor/github.com/kyoh86/exportloopref/go.mod b/vendor/github.com/kyoh86/exportloopref/go.mod
index 2b61b220b..34a53987a 100644
--- a/vendor/github.com/kyoh86/exportloopref/go.mod
+++ b/vendor/github.com/kyoh86/exportloopref/go.mod
@@ -2,4 +2,4 @@ module github.com/kyoh86/exportloopref
go 1.14
-require golang.org/x/tools v0.0.0-20200321224714-0d839f3cf2ed
+require golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa
diff --git a/vendor/github.com/kyoh86/exportloopref/go.sum b/vendor/github.com/kyoh86/exportloopref/go.sum
index eb0e5ab1e..3b199f006 100644
--- a/vendor/github.com/kyoh86/exportloopref/go.sum
+++ b/vendor/github.com/kyoh86/exportloopref/go.sum
@@ -1,4 +1,4 @@
-github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
@@ -12,8 +12,8 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20200321224714-0d839f3cf2ed h1:OCZDlBlLYiUK6T33/8+3BnojrS2W+Dg1rKYJhR89xGE=
-golang.org/x/tools v0.0.0-20200321224714-0d839f3cf2ed/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
+golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa h1:mMXQKlWCw9mIWgVLLfiycDZjMHMMYqiuakI4E/l2xcA=
+golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=