diff options
| author | Taras Madan <tarasmadan@google.com> | 2025-02-16 14:05:43 +0100 |
|---|---|---|
| committer | Taras Madan <tarasmadan@google.com> | 2025-02-17 08:18:57 +0000 |
| commit | b68182a296642f488cde3a00d4c02a4e614cc20e (patch) | |
| tree | 2c327284b6a7cdaa8ba13c732bf6c7620eda1801 | |
| parent | 40a34ec944732a2502ee67d92cc8c023355dfad4 (diff) | |
tools/syz-linter: detect loop variables scoping
Loop variables are per-iteration, not per loop since go122.
https://go.dev/blog/loopvar-preview
| -rw-r--r-- | tools/syz-linter/linter.go | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/tools/syz-linter/linter.go b/tools/syz-linter/linter.go index fec7490fc..d29e256a3 100644 --- a/tools/syz-linter/linter.go +++ b/tools/syz-linter/linter.go @@ -75,6 +75,8 @@ func run(p *analysis.Pass) (interface{}, error) { pass.checkVarDecl(n) case *ast.IfStmt: pass.checkIfStmt(n) + case *ast.AssignStmt: + pass.checkAssignStmt(n) } return true }) @@ -382,3 +384,25 @@ func (pass *Pass) nodeString(n ast.Node) string { printer.Fprint(w, pass.Fset, n) return w.String() } + +// checkAssignStmt warns about loop variables duplication attempts. +// Before go122 loop variables were per-loop, not per-iter. +func (pass *Pass) checkAssignStmt(n *ast.AssignStmt) { + if len(n.Lhs) != len(n.Rhs) { + return + } + for i, lhs := range n.Lhs { + lIdent, ok := lhs.(*ast.Ident) + if !ok { + return + } + rIdent, ok := n.Rhs[i].(*ast.Ident) + if !ok { + return + } + if lIdent.Name != rIdent.Name { + return + } + } + pass.report(n, "Don't duplicate loop variables. They are per-iter (not per-loop) since go122.") +} |
