Skip to content

Commit 2f9d2a0

Browse files
authored
fix: false-positive with int pointer dereference (#13)
* fix: false-positive with int pointer dereference * chore: use tagged version of x/tools
1 parent a928eef commit 2f9d2a0

File tree

4 files changed

+51
-16
lines changed

4 files changed

+51
-16
lines changed

durationcheck.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ func check(pass *analysis.Pass) func(ast.Node) {
7676
}
7777

7878
func isDuration(x types.Type) bool {
79-
return x.String() == "time.Duration"
79+
return x.String() == "time.Duration" || x.String() == "*time.Duration"
8080
}
8181

8282
// isUnacceptableExpr returns true if the argument is not an acceptable time.Duration expression
@@ -94,9 +94,12 @@ func isUnacceptableExpr(pass *analysis.Pass, expr ast.Expr) bool {
9494
return !isAcceptableNestedExpr(pass, e)
9595
case *ast.SelectorExpr:
9696
return !isAcceptableNestedExpr(pass, e)
97+
case *ast.StarExpr:
98+
return !isAcceptableNestedExpr(pass, e)
99+
default:
100+
return true
97101
}
98102

99-
return true
100103
}
101104

102105
// isAcceptableCast returns true if the argument is an acceptable expression cast to time.Duration
@@ -148,9 +151,11 @@ func isAcceptableNestedExpr(pass *analysis.Pass, n ast.Expr) bool {
148151
return !isDuration(t)
149152
case *ast.SelectorExpr:
150153
return isAcceptableNestedExpr(pass, e.X) && isAcceptableIdent(pass, e.Sel)
154+
case *ast.StarExpr:
155+
return isAcceptableNestedExpr(pass, e.X)
156+
default:
157+
return false
151158
}
152-
153-
return false
154159
}
155160

156161
func isAcceptableIdent(pass *analysis.Pass, ident *ast.Ident) bool {

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ module github.com/charithe/durationcheck
22

33
go 1.14
44

5-
require golang.org/x/tools v0.0.0-20200403190813-44a64ad78b9b
5+
require golang.org/x/tools v0.1.0

go.sum

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
1-
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
1+
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
22
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
33
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
4-
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
5-
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
4+
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
5+
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
6+
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
67
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
78
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
8-
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
9+
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
910
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
10-
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
11+
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
1112
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
1213
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
14+
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
15+
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k=
16+
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
1317
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
18+
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
19+
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
1420
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
15-
golang.org/x/tools v0.0.0-20200403190813-44a64ad78b9b h1:AFZdJUT7jJYXQEC29hYH/WZkoV7+KhwxQGmdZ19yYoY=
16-
golang.org/x/tools v0.0.0-20200403190813-44a64ad78b9b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
21+
golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
22+
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
1723
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
1824
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
19-
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
20-
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
25+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
26+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

testdata/src/a/a.go

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package a
22

33
import (
4-
"b"
54
"time"
5+
6+
"b"
67
)
78

89
const (
@@ -13,11 +14,12 @@ const (
1314
type myStruct struct {
1415
fieldA int
1516
fieldB time.Duration
17+
fieldC *int
1618
}
1719

1820
func validCases() {
1921
y := 10
20-
ms := myStruct{fieldA: 10, fieldB: 10 * time.Second}
22+
ms := myStruct{fieldA: 10, fieldB: 10 * time.Second, fieldC: func(v int) *int { return &v }(10)}
2123

2224
_ = time.Second * 30
2325

@@ -45,6 +47,10 @@ func validCases() {
4547

4648
_ = time.Millisecond * time.Duration(someDurationMillis())
4749

50+
_ = time.Duration(*somePointerDurationMillis()) * time.Millisecond
51+
52+
_ = time.Millisecond * time.Duration(*somePointerDurationMillis())
53+
4854
_ = timeout / time.Millisecond
4955

5056
_ = foo * time.Second
@@ -55,6 +61,10 @@ func validCases() {
5561

5662
_ = time.Second * time.Duration(ms.fieldA)
5763

64+
_ = time.Duration(*ms.fieldC) * time.Second
65+
66+
_ = time.Second * time.Duration(*ms.fieldC)
67+
5868
_ = b.SomeInt * time.Second
5969

6070
_ = time.Second * b.SomeInt
@@ -74,6 +84,10 @@ func invalidCases() {
7484

7585
_ = time.Millisecond * someDuration() // want `Multiplication of durations`
7686

87+
_ = *somePointerDuration() * time.Second // want `Multiplication of durations`
88+
89+
_ = time.Millisecond * *somePointerDuration() // want `Multiplication of durations`
90+
7791
_ = (30 * time.Second) * time.Millisecond // want `Multiplication of durations`
7892

7993
_ = time.Millisecond * (30 * time.Second) // want `Multiplication of durations`
@@ -98,3 +112,13 @@ func someDuration() time.Duration {
98112
func someDurationMillis() int {
99113
return 10
100114
}
115+
116+
func somePointerDuration() *time.Duration {
117+
v := 10 * time.Second
118+
return &v
119+
}
120+
121+
func somePointerDurationMillis() *int {
122+
v := 10
123+
return &v
124+
}

0 commit comments

Comments
 (0)