Left: | ||
Right: |
OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 The Go Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style | |
3 // license that can be found in the LICENSE file. | |
4 | |
5 /* | |
6 This file contains the code to check for suspicious shifts. | |
7 */ | |
8 | |
9 package main | |
10 | |
11 import ( | |
12 "go/ast" | |
13 "go/token" | |
14 | |
15 "code.google.com/p/go.tools/go/exact" | |
16 "code.google.com/p/go.tools/go/types" | |
17 ) | |
18 | |
19 func init() { | |
20 register("shift", | |
21 "check for suspicious shifts", | |
22 checkShift, | |
23 binaryExpr, assignStmt) | |
24 } | |
25 | |
26 func checkShift(f *File, node ast.Node) { | |
27 switch node := node.(type) { | |
28 case *ast.BinaryExpr: | |
29 if node.Op == token.SHL || node.Op == token.SHR { | |
30 checkSuspiciousShift(f, node, node.X, node.Y) | |
31 } | |
32 case *ast.AssignStmt: | |
33 if len(node.Lhs) != 1 || len(node.Rhs) != 1 { | |
34 return | |
35 } | |
36 if node.Tok == token.SHL_ASSIGN || node.Tok == token.SHR_ASSIGN { | |
37 checkSuspiciousShift(f, node, node.Lhs[0], node.Rhs[0]) | |
38 } | |
39 } | |
40 } | |
41 | |
42 // checkSuspiciousShift checks if shift or shift-assign operations shift by more | |
43 // than the length of the underlying variable. | |
44 func checkSuspiciousShift(f *File, node ast.Node, x, y ast.Expr) { | |
45 amt, ok := exact.Int64Val(f.pkg.types[y].Value) | |
josharian
2014/08/26 19:53:16
Int64Val panics when passed a nil.
And please add
| |
46 if !ok { | |
47 return | |
48 } | |
49 t := f.pkg.types[x].Type | |
50 if t != nil { | |
josharian
2014/08/26 19:53:16
This might be a bit clearer as:
if t == nil {
r
| |
51 t = t.Underlying() | |
52 } | |
53 b, ok := t.(*types.Basic) | |
54 if !ok { | |
55 return | |
56 } | |
57 var size int64 | |
58 switch b.Kind() { | |
59 case types.Uint8, types.Int8: | |
60 size = 8 | |
61 case types.Uint16, types.Int16: | |
62 size = 16 | |
63 case types.Uint32, types.Int32: | |
64 size = 32 | |
65 case types.Uint64, types.Int64: | |
66 size = 64 | |
67 default: | |
68 return | |
69 } | |
70 if amt >= size { | |
71 ident := f.gofmt(x) | |
72 f.Badf(node.Pos(), "shift of %s by %d will always be 0", ident, amt) | |
josharian
2014/08/26 19:53:16
If the value is negative, the shifted value will b
| |
73 } | |
74 } | |
OLD | NEW |