...
Source file src/pkg/cmd/vendor/golang.org/x/tools/go/analysis/passes/shift/shift.go
1
2
3
4
5
6
7 package shift
8
9
10
11
12
13 import (
14 "go/ast"
15 "go/constant"
16 "go/token"
17
18 "golang.org/x/tools/go/analysis"
19 "golang.org/x/tools/go/analysis/passes/inspect"
20 "golang.org/x/tools/go/analysis/passes/internal/analysisutil"
21 "golang.org/x/tools/go/ast/inspector"
22 )
23
24 var Analyzer = &analysis.Analyzer{
25 Name: "shift",
26 Doc: "check for shifts that equal or exceed the width of the integer",
27 Requires: []*analysis.Analyzer{inspect.Analyzer},
28 Run: run,
29 }
30
31 func run(pass *analysis.Pass) (interface{}, error) {
32 inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
33
34
35 dead := make(map[ast.Node]bool)
36 nodeFilter := []ast.Node{
37 (*ast.IfStmt)(nil),
38 (*ast.SwitchStmt)(nil),
39 }
40 inspect.Preorder(nodeFilter, func(n ast.Node) {
41
42 updateDead(pass.TypesInfo, dead, n)
43 })
44
45 nodeFilter = []ast.Node{
46 (*ast.AssignStmt)(nil),
47 (*ast.BinaryExpr)(nil),
48 }
49 inspect.Preorder(nodeFilter, func(node ast.Node) {
50 if dead[node] {
51
52 return
53 }
54
55 switch node := node.(type) {
56 case *ast.BinaryExpr:
57 if node.Op == token.SHL || node.Op == token.SHR {
58 checkLongShift(pass, node, node.X, node.Y)
59 }
60 case *ast.AssignStmt:
61 if len(node.Lhs) != 1 || len(node.Rhs) != 1 {
62 return
63 }
64 if node.Tok == token.SHL_ASSIGN || node.Tok == token.SHR_ASSIGN {
65 checkLongShift(pass, node, node.Lhs[0], node.Rhs[0])
66 }
67 }
68 })
69 return nil, nil
70 }
71
72
73
74 func checkLongShift(pass *analysis.Pass, node ast.Node, x, y ast.Expr) {
75 if pass.TypesInfo.Types[x].Value != nil {
76
77
78
79 return
80 }
81
82 v := pass.TypesInfo.Types[y].Value
83 if v == nil {
84 return
85 }
86 amt, ok := constant.Int64Val(v)
87 if !ok {
88 return
89 }
90 t := pass.TypesInfo.Types[x].Type
91 if t == nil {
92 return
93 }
94 size := 8 * pass.TypesSizes.Sizeof(t)
95 if amt >= size {
96 ident := analysisutil.Format(pass.Fset, x)
97 pass.Reportf(node.Pos(), "%s (%d bits) too small for shift of %d", ident, size, amt)
98 }
99 }
100
View as plain text