From b68182a296642f488cde3a00d4c02a4e614cc20e Mon Sep 17 00:00:00 2001 From: Taras Madan Date: Sun, 16 Feb 2025 14:05:43 +0100 Subject: tools/syz-linter: detect loop variables scoping Loop variables are per-iteration, not per loop since go122. https://go.dev/blog/loopvar-preview --- tools/syz-linter/linter.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) 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.") +} -- cgit mrf-deployment