From 74e1e4965b96ba39fe582eb76b42dd3fb5ce238e Mon Sep 17 00:00:00 2001 From: Oleg Kovalov Date: Thu, 3 Dec 2020 16:03:27 +0100 Subject: [PATCH 1/3] add bad defer unlock --- analyzer/testdata/src/extra/file.go | 12 ++++++++++++ analyzer/testdata/src/extra/rules.go | 9 +++++++++ rules.go | 10 ++++++++++ 3 files changed, 31 insertions(+) diff --git a/analyzer/testdata/src/extra/file.go b/analyzer/testdata/src/extra/file.go index ef70f1df..ba31a83b 100644 --- a/analyzer/testdata/src/extra/file.go +++ b/analyzer/testdata/src/extra/file.go @@ -371,3 +371,15 @@ func mismatchingUnlock2Struct(x *withMutex, op func()) { defer x.mu.Unlock() op() } + +func mismatchingDeferLock1(x *withMutex, op func()) { + x.mu.Lock() + defer x.mu.Lock() // want `\Qmaybe defer x.mu.Unlock() was intended?` + op() +} + +func mismatchingDeferLock2(x *withMutex, op func()) { + x.mu.RLock() + defer x.mu.RLock() // want `\Qmaybe defer x.mu.RUnlock() was intended?` + op() +} diff --git a/analyzer/testdata/src/extra/rules.go b/analyzer/testdata/src/extra/rules.go index 994fb148..a9786e98 100644 --- a/analyzer/testdata/src/extra/rules.go +++ b/analyzer/testdata/src/extra/rules.go @@ -143,4 +143,13 @@ func _(m fluent.Matcher) { m.Match(`$mu.Lock(); defer $mu.RUnlock()`).Report(`maybe $mu.RLock() was intended?`) m.Match(`$mu.RLock(); defer $mu.Unlock()`).Report(`maybe $mu.Lock() was intended?`) + + m.Match(`$mu1.Lock(); defer $mu2.Lock()`). + Where(m["mu1"].Text == m["mu2"].Text). + At(m["mu2"]). + Report(`maybe defer $mu1.Unlock() was intended?`) + m.Match(`$mu1.RLock(); defer $mu2.RLock()`). + Where(m["mu1"].Text == m["mu2"].Text). + At(m["mu2"]). + Report(`maybe defer $mu1.RUnlock() was intended?`) } diff --git a/rules.go b/rules.go index 69c13d2a..765b9bcd 100644 --- a/rules.go +++ b/rules.go @@ -396,6 +396,16 @@ func gocriticFlagDeref(m fluent.Matcher) { func gocriticBadLock(m fluent.Matcher) { m.Match(`$mu.Lock(); defer $mu.RUnlock()`).Report(`maybe $mu.RLock() was intended?`) m.Match(`$mu.RLock(); defer $mu.Unlock()`).Report(`maybe $mu.Lock() was intended?`) + + // `mu1` and `mu2` are added to make possible report line were `m2` is used (with defer) + m.Match(`$mu1.Lock(); defer $mu2.Lock()`). + Where(m["mu1"].Text == m["mu2"].Text). + At(m["mu2"]). + Report(`maybe defer $mu1.Unlock() was intended?`) + m.Match(`$mu1.RLock(); defer $mu2.RLock()`). + Where(m["mu1"].Text == m["mu2"].Text). + At(m["mu2"]). + Report(`maybe defer $mu1.RUnlock() was intended?`) } func reviveBoolLiteralInExpr(m fluent.Matcher) { From 56532936b75b6cecf1e0954302be9d52e1ca2bb1 Mon Sep 17 00:00:00 2001 From: Oleg Kovalov Date: Thu, 3 Dec 2020 16:07:55 +0100 Subject: [PATCH 2/3] more tests --- analyzer/testdata/src/extra/negative_tests.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/analyzer/testdata/src/extra/negative_tests.go b/analyzer/testdata/src/extra/negative_tests.go index a7491cae..c5517d20 100644 --- a/analyzer/testdata/src/extra/negative_tests.go +++ b/analyzer/testdata/src/extra/negative_tests.go @@ -20,6 +20,18 @@ func goodRUnlock(mu *sync.RWMutex, op func()) { op() } +func goodStrangeLocks(x1, x2 *sync.RWMutex, op func()) { + x1.Lock() + defer x2.Lock() + op() +} + +func goodStrangeRLocks(x1, x2 *sync.RWMutex, op func()) { + x1.RLock() + defer x2.RLock() + op() +} + func differentMutexes(mu1, mu2 *sync.RWMutex, op func()) { { mu2.RLock() From 8d06a78dbc8e489b9dbec8fc0972649398895180 Mon Sep 17 00:00:00 2001 From: Oleg Kovalov Date: Thu, 3 Dec 2020 16:11:57 +0100 Subject: [PATCH 3/3] fix comment grammar --- rules.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules.go b/rules.go index 765b9bcd..e337921c 100644 --- a/rules.go +++ b/rules.go @@ -397,7 +397,7 @@ func gocriticBadLock(m fluent.Matcher) { m.Match(`$mu.Lock(); defer $mu.RUnlock()`).Report(`maybe $mu.RLock() was intended?`) m.Match(`$mu.RLock(); defer $mu.Unlock()`).Report(`maybe $mu.Lock() was intended?`) - // `mu1` and `mu2` are added to make possible report line were `m2` is used (with defer) + // `mu1` and `mu2` are added to make possible report a line where `m2` is used (with a defer) m.Match(`$mu1.Lock(); defer $mu2.Lock()`). Where(m["mu1"].Text == m["mu2"].Text). At(m["mu2"]).