@@ -114,7 +114,10 @@ class CPPMutexFunctionCall extends MutexFunctionCall {
114
114
/**
115
115
* Holds if this `CPPMutexFunctionCall` is a lock.
116
116
*/
117
- override predicate isLock ( ) { getTarget ( ) .getName ( ) = "lock" }
117
+ override predicate isLock ( ) {
118
+ not isLockingOperationWithinLockingOperation ( this ) and
119
+ getTarget ( ) .getName ( ) = "lock"
120
+ }
118
121
119
122
/**
120
123
* Holds if this `CPPMutexFunctionCall` is a speculative lock, defined as calling
@@ -172,6 +175,7 @@ class CMutexFunctionCall extends MutexFunctionCall {
172
175
* Holds if this `CMutexFunctionCall` is a lock.
173
176
*/
174
177
override predicate isLock ( ) {
178
+ not isLockingOperationWithinLockingOperation ( this ) and
175
179
getTarget ( ) .getName ( ) = [ "mtx_lock" , "mtx_timedlock" , "mtx_trylock" ]
176
180
}
177
181
@@ -296,6 +300,16 @@ abstract class LockingOperation extends FunctionCall {
296
300
* Holds if this is an unlock operation
297
301
*/
298
302
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
+ }
299
313
}
300
314
301
315
/**
@@ -317,6 +331,7 @@ class RAIIStyleLock extends LockingOperation {
317
331
* Holds if this is a lock operation
318
332
*/
319
333
override predicate isLock ( ) {
334
+ not isLockingOperationWithinLockingOperation ( this ) and
320
335
this instanceof ConstructorCall and
321
336
lock = getArgument ( 0 ) .getAChild * ( ) and
322
337
// defer_locks don't cause a lock
0 commit comments