@@ -18,7 +18,7 @@ func init() {
18
18
register ("copylocks" ,
19
19
"check that locks are not passed by value" ,
20
20
checkCopyLocks ,
21
- funcDecl , rangeStmt , funcLit , assignStmt , genDecl , compositeLit )
21
+ funcDecl , rangeStmt , funcLit , callExpr , assignStmt , genDecl , compositeLit , returnStmt )
22
22
}
23
23
24
24
// checkCopyLocks checks whether node might
@@ -31,12 +31,16 @@ func checkCopyLocks(f *File, node ast.Node) {
31
31
checkCopyLocksFunc (f , node .Name .Name , node .Recv , node .Type )
32
32
case * ast.FuncLit :
33
33
checkCopyLocksFunc (f , "func" , nil , node .Type )
34
+ case * ast.CallExpr :
35
+ checkCopyLocksCallExpr (f , node )
34
36
case * ast.AssignStmt :
35
37
checkCopyLocksAssign (f , node )
36
38
case * ast.GenDecl :
37
39
checkCopyLocksGenDecl (f , node )
38
40
case * ast.CompositeLit :
39
- checkCopyCompositeLit (f , node )
41
+ checkCopyLocksCompositeLit (f , node )
42
+ case * ast.ReturnStmt :
43
+ checkCopyLocksReturnStmt (f , node )
40
44
}
41
45
}
42
46
@@ -66,8 +70,8 @@ func checkCopyLocksGenDecl(f *File, gd *ast.GenDecl) {
66
70
}
67
71
}
68
72
69
- // checkCopyCompositeLit detects lock copy inside a composite literal
70
- func checkCopyCompositeLit (f * File , cl * ast.CompositeLit ) {
73
+ // checkCopyLocksCompositeLit detects lock copy inside a composite literal
74
+ func checkCopyLocksCompositeLit (f * File , cl * ast.CompositeLit ) {
71
75
for _ , x := range cl .Elts {
72
76
if node , ok := x .(* ast.KeyValueExpr ); ok {
73
77
x = node .Value
@@ -78,6 +82,24 @@ func checkCopyCompositeLit(f *File, cl *ast.CompositeLit) {
78
82
}
79
83
}
80
84
85
+ // checkCopyLocksReturnStmt detects lock copy in return statement
86
+ func checkCopyLocksReturnStmt (f * File , rs * ast.ReturnStmt ) {
87
+ for _ , x := range rs .Results {
88
+ if path := lockPathRhs (f , x ); path != nil {
89
+ f .Badf (x .Pos (), "return copies lock value: %v" , path )
90
+ }
91
+ }
92
+ }
93
+
94
+ // checkCopyLocksCallExpr detects lock copy in function call
95
+ func checkCopyLocksCallExpr (f * File , ce * ast.CallExpr ) {
96
+ for _ , x := range ce .Args {
97
+ if path := lockPathRhs (f , x ); path != nil {
98
+ f .Badf (x .Pos (), "function call copies lock value: %v" , path )
99
+ }
100
+ }
101
+ }
102
+
81
103
// checkCopyLocksFunc checks whether a function might
82
104
// inadvertently copy a lock, by checking whether
83
105
// its receiver, parameters, or return values
0 commit comments