@@ -114,7 +114,10 @@ class CPPMutexFunctionCall extends MutexFunctionCall {
114114 /**
115115 * Holds if this `CPPMutexFunctionCall` is a lock.
116116 */
117- override predicate isLock ( ) { getTarget ( ) .getName ( ) = "lock" }
117+ override predicate isLock ( ) {
118+ not isLockingOperationWithinLockingOperation ( this ) and
119+ getTarget ( ) .getName ( ) = "lock"
120+ }
118121
119122 /**
120123 * Holds if this `CPPMutexFunctionCall` is a speculative lock, defined as calling
@@ -172,6 +175,7 @@ class CMutexFunctionCall extends MutexFunctionCall {
172175 * Holds if this `CMutexFunctionCall` is a lock.
173176 */
174177 override predicate isLock ( ) {
178+ not isLockingOperationWithinLockingOperation ( this ) and
175179 getTarget ( ) .getName ( ) = [ "mtx_lock" , "mtx_timedlock" , "mtx_trylock" ]
176180 }
177181
@@ -296,6 +300,16 @@ abstract class LockingOperation extends FunctionCall {
296300 * Holds if this is an unlock operation
297301 */
298302 abstract predicate isUnlock ( ) ;
303+
304+ /**
305+ * Holds if this locking operation is really a locking operation within a
306+ * designated locking operation. This library assumes the underlying locking
307+ * operations are implemented correctly in that calling a `LockingOperation`
308+ * results in the creation of a singular lock.
309+ */
310+ predicate isLockingOperationWithinLockingOperation ( LockingOperation inner ) {
311+ exists ( LockingOperation outer | outer .getTarget ( ) = inner .getEnclosingFunction ( ) )
312+ }
299313}
300314
301315/**
@@ -317,6 +331,7 @@ class RAIIStyleLock extends LockingOperation {
317331 * Holds if this is a lock operation
318332 */
319333 override predicate isLock ( ) {
334+ not isLockingOperationWithinLockingOperation ( this ) and
320335 this instanceof ConstructorCall and
321336 lock = getArgument ( 0 ) .getAChild * ( ) and
322337 // defer_locks don't cause a lock
0 commit comments