honnef.co/go/tools@v0.5.0-0.dev.0.20240520180541-dcae280a5e87/staticcheck/sa4022/sa4022.go (about)

     1  package sa4022
     2  
     3  import (
     4  	"go/ast"
     5  
     6  	"honnef.co/go/tools/analysis/code"
     7  	"honnef.co/go/tools/analysis/lint"
     8  	"honnef.co/go/tools/analysis/report"
     9  	"honnef.co/go/tools/pattern"
    10  
    11  	"golang.org/x/tools/go/analysis"
    12  	"golang.org/x/tools/go/analysis/passes/inspect"
    13  )
    14  
    15  var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
    16  	Analyzer: &analysis.Analyzer{
    17  		Name:     "SA4022",
    18  		Run:      run,
    19  		Requires: []*analysis.Analyzer{inspect.Analyzer},
    20  	},
    21  	Doc: &lint.Documentation{
    22  		Title:    `Comparing the address of a variable against nil`,
    23  		Text:     `Code such as \"if &x == nil\" is meaningless, because taking the address of a variable always yields a non-nil pointer.`,
    24  		Since:    "2020.1",
    25  		Severity: lint.SeverityWarning,
    26  		MergeIf:  lint.MergeIfAny,
    27  	},
    28  })
    29  
    30  var Analyzer = SCAnalyzer.Analyzer
    31  
    32  var CheckAddressIsNilQ = pattern.MustParse(
    33  	`(BinaryExpr
    34  		(UnaryExpr "&" _)
    35  		(Or "==" "!=")
    36  		(Builtin "nil"))`)
    37  
    38  func run(pass *analysis.Pass) (interface{}, error) {
    39  	fn := func(node ast.Node) {
    40  		_, ok := code.Match(pass, CheckAddressIsNilQ, node)
    41  		if !ok {
    42  			return
    43  		}
    44  		report.Report(pass, node, "the address of a variable cannot be nil")
    45  	}
    46  	code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
    47  	return nil, nil
    48  }