@@ -187,10 +187,13 @@ REQUIRES(...), REQUIRES_SHARED(...)
187187
188188*Previously *: ``EXCLUSIVE_LOCKS_REQUIRED ``, ``SHARED_LOCKS_REQUIRED ``
189189
190- ``REQUIRES `` is an attribute on functions or methods, which
190+ ``REQUIRES `` is an attribute on functions, methods or function parameters of
191+ reference to :ref: `scoped_capability `-annotated type, which
191192declares that the calling thread must have exclusive access to the given
192193capabilities. More than one capability may be specified. The capabilities
193194must be held on entry to the function, *and must still be held on exit *.
195+ Additionally, if the attribute is on a function parameter, it declares that
196+ the scoped capability manages the specified capabilities in the given order.
194197
195198``REQUIRES_SHARED `` is similar, but requires only shared access.
196199
@@ -211,17 +214,34 @@ must be held on entry to the function, *and must still be held on exit*.
211214 mu1.Unlock();
212215 }
213216
217+ void require(MutexLocker& scope REQUIRES(mu1)) {
218+ scope.Unlock();
219+ a = 0; // Warning! Requires mu1.
220+ scope.Lock();
221+ }
222+
223+ void testParameter() {
224+ MutexLocker scope(&mu1), scope2(&mu2);
225+ require(scope2); // Warning! Mutex managed by 'scope2' is 'mu2' instead of 'mu1'
226+ require(scope); // OK.
227+ scope.Unlock();
228+ require(scope); // Warning! Requires mu1.
229+ }
230+
214231
215232ACQUIRE(...), ACQUIRE_SHARED(...), RELEASE(...), RELEASE_SHARED(...), RELEASE_GENERIC(...)
216233------------------------------------------------------------------------------------------
217234
218235*Previously *: ``EXCLUSIVE_LOCK_FUNCTION ``, ``SHARED_LOCK_FUNCTION ``,
219236``UNLOCK_FUNCTION ``
220237
221- ``ACQUIRE `` and ``ACQUIRE_SHARED `` are attributes on functions or methods
222- declaring that the function acquires a capability, but does not release it.
238+ ``ACQUIRE `` and ``ACQUIRE_SHARED `` are attributes on functions, methods
239+ or function parameters of reference to :ref: `scoped_capability `-annotated type,
240+ which declare that the function acquires a capability, but does not release it.
223241The given capability must not be held on entry, and will be held on exit
224242(exclusively for ``ACQUIRE ``, shared for ``ACQUIRE_SHARED ``).
243+ Additionally, if the attribute is on a function parameter, it declares that
244+ the scoped capability manages the specified capabilities in the given order.
225245
226246``RELEASE ``, ``RELEASE_SHARED ``, and ``RELEASE_GENERIC `` declare that the
227247function releases the given capability. The capability must be held on entry
@@ -249,6 +269,14 @@ shared for ``RELEASE_GENERIC``), and will no longer be held on exit.
249269 myObject.doSomething(); // Warning, mu is not locked.
250270 }
251271
272+ void release(MutexLocker& scope RELEASE(mu)) {
273+ } // Warning! Need to unlock mu.
274+
275+ void testParameter() {
276+ MutexLocker scope(&mu);
277+ release(scope);
278+ }
279+
252280If no argument is passed to ``ACQUIRE `` or ``RELEASE ``, then the argument is
253281assumed to be ``this ``, and the analysis will not check the body of the
254282function. This pattern is intended for use by classes which hide locking
@@ -283,10 +311,13 @@ EXCLUDES(...)
283311
284312*Previously *: ``LOCKS_EXCLUDED ``
285313
286- ``EXCLUDES `` is an attribute on functions or methods, which declares that
314+ ``EXCLUDES `` is an attribute on functions, methods or function parameters
315+ of reference to :ref: `scoped_capability `-annotated type, which declares that
287316the caller must *not * hold the given capabilities. This annotation is
288317used to prevent deadlock. Many mutex implementations are not re-entrant, so
289318deadlock can occur if the function acquires the mutex a second time.
319+ Additionally, if the attribute is on a function parameter, it declares that
320+ the scoped capability manages the specified capabilities in the given order.
290321
291322.. code-block :: c++
292323
@@ -305,6 +336,16 @@ deadlock can occur if the function acquires the mutex a second time.
305336 mu.Unlock();
306337 }
307338
339+ void exclude(MutexLocker& scope LOCKS_EXCLUDED(mu)) {
340+ scope.Unlock(); // Warning! mu is not locked.
341+ scope.Lock();
342+ } // Warning! mu still held at the end of function.
343+
344+ void testParameter() {
345+ MutexLocker scope(&mu);
346+ exclude(scope); // Warning, mu is held.
347+ }
348+
308349Unlike ``REQUIRES ``, ``EXCLUDES `` is optional. The analysis will not issue a
309350warning if the attribute is missing, which can lead to false negatives in some
310351cases. This issue is discussed further in :ref: `negative `.
@@ -393,6 +434,7 @@ class can be used as a capability. The string argument specifies the kind of
393434capability in error messages, e.g. ``"mutex" ``. See the ``Container `` example
394435given above, or the ``Mutex `` class in :ref: `mutexheader `.
395436
437+ .. _scoped_capability :
396438
397439SCOPED_CAPABILITY
398440-----------------
0 commit comments