X-Git-Url: https://git.josue.xyz/?a=blobdiff_plain;f=.config%2Fcoc%2Fextensions%2Fcoc-go-data%2Ftools%2Fpkg%2Fmod%2Fgolang.org%2Fx%2Ftools%40v0.0.0-20201105173854-bc9fc8d8c4bc%2Fgo%2Fanalysis%2Fpasses%2Fshift%2Fshift.go;fp=.config%2Fcoc%2Fextensions%2Fcoc-go-data%2Ftools%2Fpkg%2Fmod%2Fgolang.org%2Fx%2Ftools%40v0.0.0-20201105173854-bc9fc8d8c4bc%2Fgo%2Fanalysis%2Fpasses%2Fshift%2Fshift.go;h=1f3df07ccd1fabea0ada98583ba268d13fb90843;hb=4d07c77cf4d78cab8639e13ddc3c22495e585b0b;hp=0000000000000000000000000000000000000000;hpb=b3950616b54221c40a7dab9099bda675007e5b6e;p=dotfiles%2F.git diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/go/analysis/passes/shift/shift.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/go/analysis/passes/shift/shift.go new file mode 100644 index 00000000..1f3df07c --- /dev/null +++ b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/go/analysis/passes/shift/shift.go @@ -0,0 +1,101 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package shift defines an Analyzer that checks for shifts that exceed +// the width of an integer. +package shift + +// TODO(adonovan): integrate with ctrflow (CFG-based) dead code analysis. May +// have impedance mismatch due to its (non-)treatment of constant +// expressions (such as runtime.GOARCH=="386"). + +import ( + "go/ast" + "go/constant" + "go/token" + + "golang.org/x/tools/go/analysis" + "golang.org/x/tools/go/analysis/passes/inspect" + "golang.org/x/tools/go/analysis/passes/internal/analysisutil" + "golang.org/x/tools/go/ast/inspector" +) + +const Doc = "check for shifts that equal or exceed the width of the integer" + +var Analyzer = &analysis.Analyzer{ + Name: "shift", + Doc: Doc, + Requires: []*analysis.Analyzer{inspect.Analyzer}, + Run: run, +} + +func run(pass *analysis.Pass) (interface{}, error) { + inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) + + // Do a complete pass to compute dead nodes. + dead := make(map[ast.Node]bool) + nodeFilter := []ast.Node{ + (*ast.IfStmt)(nil), + (*ast.SwitchStmt)(nil), + } + inspect.Preorder(nodeFilter, func(n ast.Node) { + // TODO(adonovan): move updateDead into this file. + updateDead(pass.TypesInfo, dead, n) + }) + + nodeFilter = []ast.Node{ + (*ast.AssignStmt)(nil), + (*ast.BinaryExpr)(nil), + } + inspect.Preorder(nodeFilter, func(node ast.Node) { + if dead[node] { + // Skip shift checks on unreachable nodes. + return + } + + switch node := node.(type) { + case *ast.BinaryExpr: + if node.Op == token.SHL || node.Op == token.SHR { + checkLongShift(pass, node, node.X, node.Y) + } + case *ast.AssignStmt: + if len(node.Lhs) != 1 || len(node.Rhs) != 1 { + return + } + if node.Tok == token.SHL_ASSIGN || node.Tok == token.SHR_ASSIGN { + checkLongShift(pass, node, node.Lhs[0], node.Rhs[0]) + } + } + }) + return nil, nil +} + +// checkLongShift checks if shift or shift-assign operations shift by more than +// the length of the underlying variable. +func checkLongShift(pass *analysis.Pass, node ast.Node, x, y ast.Expr) { + if pass.TypesInfo.Types[x].Value != nil { + // Ignore shifts of constants. + // These are frequently used for bit-twiddling tricks + // like ^uint(0) >> 63 for 32/64 bit detection and compatibility. + return + } + + v := pass.TypesInfo.Types[y].Value + if v == nil { + return + } + amt, ok := constant.Int64Val(v) + if !ok { + return + } + t := pass.TypesInfo.Types[x].Type + if t == nil { + return + } + size := 8 * pass.TypesSizes.Sizeof(t) + if amt >= size { + ident := analysisutil.Format(pass.Fset, x) + pass.ReportRangef(node, "%s (%d bits) too small for shift of %d", ident, size, amt) + } +}