xref: /llvm-project/clang/docs/ThreadSafetyAnalysis.rst (revision c1e7e4500c6e3b921f5e0cda8ba8d8d66e086db6)
1
2======================
3Thread Safety Analysis
4======================
5
6Introduction
7============
8
9Clang Thread Safety Analysis is a C++ language extension which warns about
10potential race conditions in code.  The analysis is completely static (i.e.
11compile-time); there is no run-time overhead.  The analysis is still
12under active development, but it is mature enough to be deployed in an
13industrial setting.  It is being developed by Google, in collaboration with
14CERT/SEI, and is used extensively in Google's internal code base.
15
16Thread safety analysis works very much like a type system for multi-threaded
17programs.  In addition to declaring the *type* of data (e.g. ``int``, ``float``,
18etc.), the programmer can (optionally) declare how access to that data is
19controlled in a multi-threaded environment.  For example, if ``foo`` is
20*guarded by* the mutex ``mu``, then the analysis will issue a warning whenever
21a piece of code reads or writes to ``foo`` without first locking ``mu``.
22Similarly, if there are particular routines that should only be called by
23the GUI thread, then the analysis will warn if other threads call those
24routines.
25
26Getting Started
27----------------
28
29.. code-block:: c++
30
31  #include "mutex.h"
32
33  class BankAccount {
34  private:
35    Mutex mu;
36    int   balance GUARDED_BY(mu);
37
38    void depositImpl(int amount) {
39      balance += amount;       // WARNING! Cannot write balance without locking mu.
40    }
41
42    void withdrawImpl(int amount) REQUIRES(mu) {
43      balance -= amount;       // OK. Caller must have locked mu.
44    }
45
46  public:
47    void withdraw(int amount) {
48      mu.Lock();
49      withdrawImpl(amount);    // OK.  We've locked mu.
50    }                          // WARNING!  Failed to unlock mu.
51
52    void transferFrom(BankAccount& b, int amount) {
53      mu.Lock();
54      b.withdrawImpl(amount);  // WARNING!  Calling withdrawImpl() requires locking b.mu.
55      depositImpl(amount);     // OK.  depositImpl() has no requirements.
56      mu.Unlock();
57    }
58  };
59
60This example demonstrates the basic concepts behind the analysis.  The
61``GUARDED_BY`` attribute declares that a thread must lock ``mu`` before it can
62read or write to ``balance``, thus ensuring that the increment and decrement
63operations are atomic.  Similarly, ``REQUIRES`` declares that
64the calling thread must lock ``mu`` before calling ``withdrawImpl``.
65Because the caller is assumed to have locked ``mu``, it is safe to modify
66``balance`` within the body of the method.
67
68The ``depositImpl()`` method does not have ``REQUIRES``, so the
69analysis issues a warning.  Thread safety analysis is not inter-procedural, so
70caller requirements must be explicitly declared.
71There is also a warning in ``transferFrom()``, because although the method
72locks ``this->mu``, it does not lock ``b.mu``.  The analysis understands
73that these are two separate mutexes, in two different objects.
74
75Finally, there is a warning in the ``withdraw()`` method, because it fails to
76unlock ``mu``.  Every lock must have a corresponding unlock, and the analysis
77will detect both double locks, and double unlocks.  A function is allowed to
78acquire a lock without releasing it, (or vice versa), but it must be annotated
79as such (using ``ACQUIRE``/``RELEASE``).
80
81
82Running The Analysis
83--------------------
84
85To run the analysis, simply compile with the ``-Wthread-safety`` flag, e.g.
86
87.. code-block:: bash
88
89  clang -c -Wthread-safety example.cpp
90
91Note that this example assumes the presence of a suitably annotated
92:ref:`mutexheader` that declares which methods perform locking,
93unlocking, and so on.
94
95
96Basic Concepts: Capabilities
97============================
98
99Thread safety analysis provides a way of protecting *resources* with
100*capabilities*.  A resource is either a data member, or a function/method
101that provides access to some underlying resource.  The analysis ensures that
102the calling thread cannot access the *resource* (i.e. call the function, or
103read/write the data) unless it has the *capability* to do so.
104
105Capabilities are associated with named C++ objects which declare specific
106methods to acquire and release the capability.  The name of the object serves
107to identify the capability.  The most common example is a mutex.  For example,
108if ``mu`` is a mutex, then calling ``mu.Lock()`` causes the calling thread
109to acquire the capability to access data that is protected by ``mu``. Similarly,
110calling ``mu.Unlock()`` releases that capability.
111
112A thread may hold a capability either *exclusively* or *shared*.  An exclusive
113capability can be held by only one thread at a time, while a shared capability
114can be held by many threads at the same time.  This mechanism enforces a
115multiple-reader, single-writer pattern.  Write operations to protected data
116require exclusive access, while read operations require only shared access.
117
118At any given moment during program execution, a thread holds a specific set of
119capabilities (e.g. the set of mutexes that it has locked.)  These act like keys
120or tokens that allow the thread to access a given resource.  Just like physical
121security keys, a thread cannot make copy of a capability, nor can it destroy
122one.  A thread can only release a capability to another thread, or acquire one
123from another thread.  The annotations are deliberately agnostic about the
124exact mechanism used to acquire and release capabilities; it assumes that the
125underlying implementation (e.g. the Mutex implementation) does the handoff in
126an appropriate manner.
127
128The set of capabilities that are actually held by a given thread at a given
129point in program execution is a run-time concept.  The static analysis works
130by calculating an approximation of that set, called the *capability
131environment*.  The capability environment is calculated for every program point,
132and describes the set of capabilities that are statically known to be held, or
133not held, at that particular point.  This environment is a conservative
134approximation of the full set of capabilities that will actually held by a
135thread at run-time.
136
137
138Reference Guide
139===============
140
141The thread safety analysis uses attributes to declare threading constraints.
142Attributes must be attached to named declarations, such as classes, methods,
143and data members. Users are *strongly advised* to define macros for the various
144attributes; example definitions can be found in :ref:`mutexheader`, below.
145The following documentation assumes the use of macros.
146
147The attributes only control assumptions made by thread safety analysis and the
148warnings it issues.  They don't affect generated code or behavior at run-time.
149
150For historical reasons, prior versions of thread safety used macro names that
151were very lock-centric.  These macros have since been renamed to fit a more
152general capability model.  The prior names are still in use, and will be
153mentioned under the tag *previously* where appropriate.
154
155
156GUARDED_BY(c) and PT_GUARDED_BY(c)
157----------------------------------
158
159``GUARDED_BY`` is an attribute on data members, which declares that the data
160member is protected by the given capability.  Read operations on the data
161require shared access, while write operations require exclusive access.
162
163``PT_GUARDED_BY`` is similar, but is intended for use on pointers and smart
164pointers. There is no constraint on the data member itself, but the *data that
165it points to* is protected by the given capability.
166
167.. code-block:: c++
168
169  Mutex mu;
170  int *p1             GUARDED_BY(mu);
171  int *p2             PT_GUARDED_BY(mu);
172  unique_ptr<int> p3  PT_GUARDED_BY(mu);
173
174  void test() {
175    p1 = 0;             // Warning!
176
177    *p2 = 42;           // Warning!
178    p2 = new int;       // OK.
179
180    *p3 = 42;           // Warning!
181    p3.reset(new int);  // OK.
182  }
183
184
185REQUIRES(...), REQUIRES_SHARED(...)
186-----------------------------------
187
188*Previously*: ``EXCLUSIVE_LOCKS_REQUIRED``, ``SHARED_LOCKS_REQUIRED``
189
190``REQUIRES`` is an attribute on functions, methods or function parameters of
191reference to :ref:`scoped_capability`-annotated type, which
192declares that the calling thread must have exclusive access to the given
193capabilities.  More than one capability may be specified.  The capabilities
194must be held on entry to the function, *and must still be held on exit*.
195Additionally, if the attribute is on a function parameter, it declares that
196the scoped capability manages the specified capabilities in the given order.
197
198``REQUIRES_SHARED`` is similar, but requires only shared access.
199
200.. code-block:: c++
201
202  Mutex mu1, mu2;
203  int a GUARDED_BY(mu1);
204  int b GUARDED_BY(mu2);
205
206  void foo() REQUIRES(mu1, mu2) {
207    a = 0;
208    b = 0;
209  }
210
211  void test() {
212    mu1.Lock();
213    foo();         // Warning!  Requires mu2.
214    mu1.Unlock();
215  }
216
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
231
232ACQUIRE(...), ACQUIRE_SHARED(...), RELEASE(...), RELEASE_SHARED(...), RELEASE_GENERIC(...)
233------------------------------------------------------------------------------------------
234
235*Previously*: ``EXCLUSIVE_LOCK_FUNCTION``, ``SHARED_LOCK_FUNCTION``,
236``UNLOCK_FUNCTION``
237
238``ACQUIRE`` and ``ACQUIRE_SHARED`` are attributes on functions, methods
239or function parameters of reference to :ref:`scoped_capability`-annotated type,
240which declare that the function acquires a capability, but does not release it.
241The given capability must not be held on entry, and will be held on exit
242(exclusively for ``ACQUIRE``, shared for ``ACQUIRE_SHARED``).
243Additionally, if the attribute is on a function parameter, it declares that
244the scoped capability manages the specified capabilities in the given order.
245
246``RELEASE``, ``RELEASE_SHARED``, and ``RELEASE_GENERIC`` declare that the
247function releases the given capability.  The capability must be held on entry
248(exclusively for ``RELEASE``, shared for ``RELEASE_SHARED``, exclusively or
249shared for ``RELEASE_GENERIC``), and will no longer be held on exit.
250
251.. code-block:: c++
252
253  Mutex mu;
254  MyClass myObject GUARDED_BY(mu);
255
256  void lockAndInit() ACQUIRE(mu) {
257    mu.Lock();
258    myObject.init();
259  }
260
261  void cleanupAndUnlock() RELEASE(mu) {
262    myObject.cleanup();
263  }                          // Warning!  Need to unlock mu.
264
265  void test() {
266    lockAndInit();
267    myObject.doSomething();
268    cleanupAndUnlock();
269    myObject.doSomething();  // Warning, mu is not locked.
270  }
271
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
280If no argument is passed to ``ACQUIRE`` or ``RELEASE``, then the argument is
281assumed to be ``this``, and the analysis will not check the body of the
282function.  This pattern is intended for use by classes which hide locking
283details behind an abstract interface.  For example:
284
285.. code-block:: c++
286
287  template <class T>
288  class CAPABILITY("mutex") Container {
289  private:
290    Mutex mu;
291    T* data;
292
293  public:
294    // Hide mu from public interface.
295    void Lock()   ACQUIRE() { mu.Lock(); }
296    void Unlock() RELEASE() { mu.Unlock(); }
297
298    T& getElem(int i) { return data[i]; }
299  };
300
301  void test() {
302    Container<int> c;
303    c.Lock();
304    int i = c.getElem(0);
305    c.Unlock();
306  }
307
308
309EXCLUDES(...)
310-------------
311
312*Previously*: ``LOCKS_EXCLUDED``
313
314``EXCLUDES`` is an attribute on functions, methods or function parameters
315of reference to :ref:`scoped_capability`-annotated type, which declares that
316the caller must *not* hold the given capabilities.  This annotation is
317used to prevent deadlock.  Many mutex implementations are not re-entrant, so
318deadlock can occur if the function acquires the mutex a second time.
319Additionally, if the attribute is on a function parameter, it declares that
320the scoped capability manages the specified capabilities in the given order.
321
322.. code-block:: c++
323
324  Mutex mu;
325  int a GUARDED_BY(mu);
326
327  void clear() EXCLUDES(mu) {
328    mu.Lock();
329    a = 0;
330    mu.Unlock();
331  }
332
333  void reset() {
334    mu.Lock();
335    clear();     // Warning!  Caller cannot hold 'mu'.
336    mu.Unlock();
337  }
338
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
349Unlike ``REQUIRES``, ``EXCLUDES`` is optional.  The analysis will not issue a
350warning if the attribute is missing, which can lead to false negatives in some
351cases.  This issue is discussed further in :ref:`negative`.
352
353
354NO_THREAD_SAFETY_ANALYSIS
355-------------------------
356
357``NO_THREAD_SAFETY_ANALYSIS`` is an attribute on functions or methods, which
358turns off thread safety checking for that method.  It provides an escape hatch
359for functions which are either (1) deliberately thread-unsafe, or (2) are
360thread-safe, but too complicated for the analysis to understand.  Reasons for
361(2) will be described in the :ref:`limitations`, below.
362
363.. code-block:: c++
364
365  class Counter {
366    Mutex mu;
367    int a GUARDED_BY(mu);
368
369    void unsafeIncrement() NO_THREAD_SAFETY_ANALYSIS { a++; }
370  };
371
372Unlike the other attributes, NO_THREAD_SAFETY_ANALYSIS is not part of the
373interface of a function, and should thus be placed on the function definition
374(in the ``.cc`` or ``.cpp`` file) rather than on the function declaration
375(in the header).
376
377
378RETURN_CAPABILITY(c)
379--------------------
380
381*Previously*: ``LOCK_RETURNED``
382
383``RETURN_CAPABILITY`` is an attribute on functions or methods, which declares
384that the function returns a reference to the given capability.  It is used to
385annotate getter methods that return mutexes.
386
387.. code-block:: c++
388
389  class MyClass {
390  private:
391    Mutex mu;
392    int a GUARDED_BY(mu);
393
394  public:
395    Mutex* getMu() RETURN_CAPABILITY(mu) { return &mu; }
396
397    // analysis knows that getMu() == mu
398    void clear() REQUIRES(getMu()) { a = 0; }
399  };
400
401
402ACQUIRED_BEFORE(...), ACQUIRED_AFTER(...)
403-----------------------------------------
404
405``ACQUIRED_BEFORE`` and ``ACQUIRED_AFTER`` are attributes on member
406declarations, specifically declarations of mutexes or other capabilities.
407These declarations enforce a particular order in which the mutexes must be
408acquired, in order to prevent deadlock.
409
410.. code-block:: c++
411
412  Mutex m1;
413  Mutex m2 ACQUIRED_AFTER(m1);
414
415  // Alternative declaration
416  // Mutex m2;
417  // Mutex m1 ACQUIRED_BEFORE(m2);
418
419  void foo() {
420    m2.Lock();
421    m1.Lock();  // Warning!  m2 must be acquired after m1.
422    m1.Unlock();
423    m2.Unlock();
424  }
425
426
427CAPABILITY(<string>)
428--------------------
429
430*Previously*: ``LOCKABLE``
431
432``CAPABILITY`` is an attribute on classes, which specifies that objects of the
433class can be used as a capability.  The string argument specifies the kind of
434capability in error messages, e.g. ``"mutex"``.  See the ``Container`` example
435given above, or the ``Mutex`` class in :ref:`mutexheader`.
436
437.. _scoped_capability:
438
439SCOPED_CAPABILITY
440-----------------
441
442*Previously*: ``SCOPED_LOCKABLE``
443
444``SCOPED_CAPABILITY`` is an attribute on classes that implement RAII-style
445locking, in which a capability is acquired in the constructor, and released in
446the destructor.  Such classes require special handling because the constructor
447and destructor refer to the capability via different names; see the
448``MutexLocker`` class in :ref:`mutexheader`, below.
449
450Scoped capabilities are treated as capabilities that are implicitly acquired
451on construction and released on destruction. They are associated with
452the set of (regular) capabilities named in thread safety attributes on the
453constructor or function returning them by value (using C++17 guaranteed copy
454elision). Acquire-type attributes on other member functions are treated as
455applying to that set of associated capabilities, while ``RELEASE`` implies that
456a function releases all associated capabilities in whatever mode they're held.
457
458
459TRY_ACQUIRE(<bool>, ...), TRY_ACQUIRE_SHARED(<bool>, ...)
460---------------------------------------------------------
461
462*Previously:* ``EXCLUSIVE_TRYLOCK_FUNCTION``, ``SHARED_TRYLOCK_FUNCTION``
463
464These are attributes on a function or method that tries to acquire the given
465capability, and returns a boolean value indicating success or failure.
466The first argument must be ``true`` or ``false``, to specify which return value
467indicates success, and the remaining arguments are interpreted in the same way
468as ``ACQUIRE``.  See :ref:`mutexheader`, below, for example uses.
469
470Because the analysis doesn't support conditional locking, a capability is
471treated as acquired after the first branch on the return value of a try-acquire
472function.
473
474.. code-block:: c++
475
476  Mutex mu;
477  int a GUARDED_BY(mu);
478
479  void foo() {
480    bool success = mu.TryLock();
481    a = 0;         // Warning, mu is not locked.
482    if (success) {
483      a = 0;       // Ok.
484      mu.Unlock();
485    } else {
486      a = 0;       // Warning, mu is not locked.
487    }
488  }
489
490
491ASSERT_CAPABILITY(...) and ASSERT_SHARED_CAPABILITY(...)
492--------------------------------------------------------
493
494*Previously:*  ``ASSERT_EXCLUSIVE_LOCK``, ``ASSERT_SHARED_LOCK``
495
496These are attributes on a function or method which asserts the calling thread
497already holds the given capability, for example by performing a run-time test
498and terminating if the capability is not held.  Presence of this annotation
499causes the analysis to assume the capability is held after calls to the
500annotated function.  See :ref:`mutexheader`, below, for example uses.
501
502
503GUARDED_VAR and PT_GUARDED_VAR
504------------------------------
505
506Use of these attributes has been deprecated.
507
508
509Warning flags
510-------------
511
512* ``-Wthread-safety``:  Umbrella flag which turns on the following:
513
514  + ``-Wthread-safety-attributes``: Semantic checks for thread safety attributes.
515  + ``-Wthread-safety-analysis``: The core analysis.
516  + ``-Wthread-safety-precise``: Requires that mutex expressions match precisely.
517       This warning can be disabled for code which has a lot of aliases.
518  + ``-Wthread-safety-reference``: Checks when guarded members are passed by reference.
519
520
521:ref:`negative` are an experimental feature, which are enabled with:
522
523* ``-Wthread-safety-negative``:  Negative capabilities.  Off by default.
524
525When new features and checks are added to the analysis, they can often introduce
526additional warnings.  Those warnings are initially released as *beta* warnings
527for a period of time, after which they are migrated into the standard analysis.
528
529* ``-Wthread-safety-beta``:  New features.  Off by default.
530
531
532.. _negative:
533
534Negative Capabilities
535=====================
536
537Thread Safety Analysis is designed to prevent both race conditions and
538deadlock.  The GUARDED_BY and REQUIRES attributes prevent race conditions, by
539ensuring that a capability is held before reading or writing to guarded data,
540and the EXCLUDES attribute prevents deadlock, by making sure that a mutex is
541*not* held.
542
543However, EXCLUDES is an optional attribute, and does not provide the same
544safety guarantee as REQUIRES.  In particular:
545
546  * A function which acquires a capability does not have to exclude it.
547  * A function which calls a function that excludes a capability does not
548    have transitively exclude that capability.
549
550As a result, EXCLUDES can easily produce false negatives:
551
552.. code-block:: c++
553
554  class Foo {
555    Mutex mu;
556
557    void foo() {
558      mu.Lock();
559      bar();           // No warning.
560      baz();           // No warning.
561      mu.Unlock();
562    }
563
564    void bar() {       // No warning.  (Should have EXCLUDES(mu)).
565      mu.Lock();
566      // ...
567      mu.Unlock();
568    }
569
570    void baz() {
571      bif();           // No warning.  (Should have EXCLUDES(mu)).
572    }
573
574    void bif() EXCLUDES(mu);
575  };
576
577
578Negative requirements are an alternative EXCLUDES that provide
579a stronger safety guarantee.  A negative requirement uses the  REQUIRES
580attribute, in conjunction with the ``!`` operator, to indicate that a capability
581should *not* be held.
582
583For example, using ``REQUIRES(!mu)`` instead of ``EXCLUDES(mu)`` will produce
584the appropriate warnings:
585
586.. code-block:: c++
587
588  class FooNeg {
589    Mutex mu;
590
591    void foo() REQUIRES(!mu) {   // foo() now requires !mu.
592      mu.Lock();
593      bar();
594      baz();
595      mu.Unlock();
596    }
597
598    void bar() {
599      mu.Lock();       // WARNING!  Missing REQUIRES(!mu).
600      // ...
601      mu.Unlock();
602    }
603
604    void baz() {
605      bif();           // WARNING!  Missing REQUIRES(!mu).
606    }
607
608    void bif() REQUIRES(!mu);
609  };
610
611
612Negative requirements are an experimental feature which is off by default,
613because it will produce many warnings in existing code.  It can be enabled
614by passing ``-Wthread-safety-negative``.
615
616
617.. _faq:
618
619Frequently Asked Questions
620==========================
621
622(Q) Should I put attributes in the header file, or in the .cc/.cpp/.cxx file?
623
624(A) Attributes are part of the formal interface of a function, and should
625always go in the header, where they are visible to anything that includes
626the header.  Attributes in the .cpp file are not visible outside of the
627immediate translation unit, which leads to false negatives and false positives.
628
629
630(Q) "*Mutex is not locked on every path through here?*"  What does that mean?
631
632(A) See :ref:`conditional_locks`, below.
633
634
635.. _limitations:
636
637Known Limitations
638=================
639
640Lexical scope
641-------------
642
643Thread safety attributes contain ordinary C++ expressions, and thus follow
644ordinary C++ scoping rules.  In particular, this means that mutexes and other
645capabilities must be declared before they can be used in an attribute.
646Use-before-declaration is okay within a single class, because attributes are
647parsed at the same time as method bodies. (C++ delays parsing of method bodies
648until the end of the class.)  However, use-before-declaration is not allowed
649between classes, as illustrated below.
650
651.. code-block:: c++
652
653  class Foo;
654
655  class Bar {
656    void bar(Foo* f) REQUIRES(f->mu);  // Error: mu undeclared.
657  };
658
659  class Foo {
660    Mutex mu;
661  };
662
663
664Private Mutexes
665---------------
666
667Good software engineering practice dictates that mutexes should be private
668members, because the locking mechanism used by a thread-safe class is part of
669its internal implementation.  However, private mutexes can sometimes leak into
670the public interface of a class.
671Thread safety attributes follow normal C++ access restrictions, so if ``mu``
672is a private member of ``c``, then it is an error to write ``c.mu`` in an
673attribute.
674
675One workaround is to (ab)use the ``RETURN_CAPABILITY`` attribute to provide a
676public *name* for a private mutex, without actually exposing the underlying
677mutex.  For example:
678
679.. code-block:: c++
680
681  class MyClass {
682  private:
683    Mutex mu;
684
685  public:
686    // For thread safety analysis only.  Does not need to be defined.
687    Mutex* getMu() RETURN_CAPABILITY(mu);
688
689    void doSomething() REQUIRES(mu);
690  };
691
692  void doSomethingTwice(MyClass& c) REQUIRES(c.getMu()) {
693    // The analysis thinks that c.getMu() == c.mu
694    c.doSomething();
695    c.doSomething();
696  }
697
698In the above example, ``doSomethingTwice()`` is an external routine that
699requires ``c.mu`` to be locked, which cannot be declared directly because ``mu``
700is private.  This pattern is discouraged because it
701violates encapsulation, but it is sometimes necessary, especially when adding
702annotations to an existing code base.  The workaround is to define ``getMu()``
703as a fake getter method, which is provided only for the benefit of thread
704safety analysis.
705
706
707.. _conditional_locks:
708
709No conditionally held locks.
710----------------------------
711
712The analysis must be able to determine whether a lock is held, or not held, at
713every program point.  Thus, sections of code where a lock *might be held* will
714generate spurious warnings (false positives).  For example:
715
716.. code-block:: c++
717
718  void foo() {
719    bool b = needsToLock();
720    if (b) mu.Lock();
721    ...  // Warning!  Mutex 'mu' is not held on every path through here.
722    if (b) mu.Unlock();
723  }
724
725
726No checking inside constructors and destructors.
727------------------------------------------------
728
729The analysis currently does not do any checking inside constructors or
730destructors.  In other words, every constructor and destructor is treated as
731if it was annotated with ``NO_THREAD_SAFETY_ANALYSIS``.
732The reason for this is that during initialization, only one thread typically
733has access to the object which is being initialized, and it is thus safe (and
734common practice) to initialize guarded members without acquiring any locks.
735The same is true of destructors.
736
737Ideally, the analysis would allow initialization of guarded members inside the
738object being initialized or destroyed, while still enforcing the usual access
739restrictions on everything else.  However, this is difficult to enforce in
740practice, because in complex pointer-based data structures, it is hard to
741determine what data is owned by the enclosing object.
742
743No inlining.
744------------
745
746Thread safety analysis is strictly intra-procedural, just like ordinary type
747checking.  It relies only on the declared attributes of a function, and will
748not attempt to inline any method calls.  As a result, code such as the
749following will not work:
750
751.. code-block:: c++
752
753  template<class T>
754  class AutoCleanup {
755    T* object;
756    void (T::*mp)();
757
758  public:
759    AutoCleanup(T* obj, void (T::*imp)()) : object(obj), mp(imp) { }
760    ~AutoCleanup() { (object->*mp)(); }
761  };
762
763  Mutex mu;
764  void foo() {
765    mu.Lock();
766    AutoCleanup<Mutex>(&mu, &Mutex::Unlock);
767    // ...
768  }  // Warning, mu is not unlocked.
769
770In this case, the destructor of ``Autocleanup`` calls ``mu.Unlock()``, so
771the warning is bogus.  However,
772thread safety analysis cannot see the unlock, because it does not attempt to
773inline the destructor.  Moreover, there is no way to annotate the destructor,
774because the destructor is calling a function that is not statically known.
775This pattern is simply not supported.
776
777
778No alias analysis.
779------------------
780
781The analysis currently does not track pointer aliases.  Thus, there can be
782false positives if two pointers both point to the same mutex.
783
784
785.. code-block:: c++
786
787  class MutexUnlocker {
788    Mutex* mu;
789
790  public:
791    MutexUnlocker(Mutex* m) RELEASE(m) : mu(m)  { mu->Unlock(); }
792    ~MutexUnlocker() ACQUIRE(mu) { mu->Lock(); }
793  };
794
795  Mutex mutex;
796  void test() REQUIRES(mutex) {
797    {
798      MutexUnlocker munl(&mutex);  // unlocks mutex
799      doSomeIO();
800    }                              // Warning: locks munl.mu
801  }
802
803The MutexUnlocker class is intended to be the dual of the MutexLocker class,
804defined in :ref:`mutexheader`.  However, it doesn't work because the analysis
805doesn't know that munl.mu == mutex.  The SCOPED_CAPABILITY attribute handles
806aliasing for MutexLocker, but does so only for that particular pattern.
807
808
809ACQUIRED_BEFORE(...) and ACQUIRED_AFTER(...) support is still experimental.
810---------------------------------------------------------------------------
811
812ACQUIRED_BEFORE(...) and ACQUIRED_AFTER(...) are currently being developed under
813the ``-Wthread-safety-beta`` flag.
814
815
816.. _mutexheader:
817
818mutex.h
819=======
820
821Thread safety analysis can be used with any threading library, but it does
822require that the threading API be wrapped in classes and methods which have the
823appropriate annotations.  The following code provides ``mutex.h`` as an example;
824these methods should be filled in to call the appropriate underlying
825implementation.
826
827
828.. code-block:: c++
829
830
831  #ifndef THREAD_SAFETY_ANALYSIS_MUTEX_H
832  #define THREAD_SAFETY_ANALYSIS_MUTEX_H
833
834  // Enable thread safety attributes only with clang.
835  // The attributes can be safely erased when compiling with other compilers.
836  #if defined(__clang__) && (!defined(SWIG))
837  #define THREAD_ANNOTATION_ATTRIBUTE__(x)   __attribute__((x))
838  #else
839  #define THREAD_ANNOTATION_ATTRIBUTE__(x)   // no-op
840  #endif
841
842  #define CAPABILITY(x) \
843    THREAD_ANNOTATION_ATTRIBUTE__(capability(x))
844
845  #define SCOPED_CAPABILITY \
846    THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
847
848  #define GUARDED_BY(x) \
849    THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
850
851  #define PT_GUARDED_BY(x) \
852    THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
853
854  #define ACQUIRED_BEFORE(...) \
855    THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))
856
857  #define ACQUIRED_AFTER(...) \
858    THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__))
859
860  #define REQUIRES(...) \
861    THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__))
862
863  #define REQUIRES_SHARED(...) \
864    THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__))
865
866  #define ACQUIRE(...) \
867    THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__))
868
869  #define ACQUIRE_SHARED(...) \
870    THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__))
871
872  #define RELEASE(...) \
873    THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__))
874
875  #define RELEASE_SHARED(...) \
876    THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__))
877
878  #define RELEASE_GENERIC(...) \
879    THREAD_ANNOTATION_ATTRIBUTE__(release_generic_capability(__VA_ARGS__))
880
881  #define TRY_ACQUIRE(...) \
882    THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__))
883
884  #define TRY_ACQUIRE_SHARED(...) \
885    THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__))
886
887  #define EXCLUDES(...) \
888    THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
889
890  #define ASSERT_CAPABILITY(x) \
891    THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x))
892
893  #define ASSERT_SHARED_CAPABILITY(x) \
894    THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x))
895
896  #define RETURN_CAPABILITY(x) \
897    THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
898
899  #define NO_THREAD_SAFETY_ANALYSIS \
900    THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
901
902
903  // Defines an annotated interface for mutexes.
904  // These methods can be implemented to use any internal mutex implementation.
905  class CAPABILITY("mutex") Mutex {
906  public:
907    // Acquire/lock this mutex exclusively.  Only one thread can have exclusive
908    // access at any one time.  Write operations to guarded data require an
909    // exclusive lock.
910    void Lock() ACQUIRE();
911
912    // Acquire/lock this mutex for read operations, which require only a shared
913    // lock.  This assumes a multiple-reader, single writer semantics.  Multiple
914    // threads may acquire the mutex simultaneously as readers, but a writer
915    // must wait for all of them to release the mutex before it can acquire it
916    // exclusively.
917    void ReaderLock() ACQUIRE_SHARED();
918
919    // Release/unlock an exclusive mutex.
920    void Unlock() RELEASE();
921
922    // Release/unlock a shared mutex.
923    void ReaderUnlock() RELEASE_SHARED();
924
925    // Generic unlock, can unlock exclusive and shared mutexes.
926    void GenericUnlock() RELEASE_GENERIC();
927
928    // Try to acquire the mutex.  Returns true on success, and false on failure.
929    bool TryLock() TRY_ACQUIRE(true);
930
931    // Try to acquire the mutex for read operations.
932    bool ReaderTryLock() TRY_ACQUIRE_SHARED(true);
933
934    // Assert that this mutex is currently held by the calling thread.
935    void AssertHeld() ASSERT_CAPABILITY(this);
936
937    // Assert that is mutex is currently held for read operations.
938    void AssertReaderHeld() ASSERT_SHARED_CAPABILITY(this);
939
940    // For negative capabilities.
941    const Mutex& operator!() const { return *this; }
942  };
943
944  // Tag types for selecting a constructor.
945  struct adopt_lock_t {} inline constexpr adopt_lock = {};
946  struct defer_lock_t {} inline constexpr defer_lock = {};
947  struct shared_lock_t {} inline constexpr shared_lock = {};
948
949  // MutexLocker is an RAII class that acquires a mutex in its constructor, and
950  // releases it in its destructor.
951  class SCOPED_CAPABILITY MutexLocker {
952  private:
953    Mutex* mut;
954    bool locked;
955
956  public:
957    // Acquire mu, implicitly acquire *this and associate it with mu.
958    MutexLocker(Mutex *mu) ACQUIRE(mu) : mut(mu), locked(true) {
959      mu->Lock();
960    }
961
962    // Assume mu is held, implicitly acquire *this and associate it with mu.
963    MutexLocker(Mutex *mu, adopt_lock_t) REQUIRES(mu) : mut(mu), locked(true) {}
964
965    // Acquire mu in shared mode, implicitly acquire *this and associate it with mu.
966    MutexLocker(Mutex *mu, shared_lock_t) ACQUIRE_SHARED(mu) : mut(mu), locked(true) {
967      mu->ReaderLock();
968    }
969
970    // Assume mu is held in shared mode, implicitly acquire *this and associate it with mu.
971    MutexLocker(Mutex *mu, adopt_lock_t, shared_lock_t) REQUIRES_SHARED(mu)
972      : mut(mu), locked(true) {}
973
974    // Assume mu is not held, implicitly acquire *this and associate it with mu.
975    MutexLocker(Mutex *mu, defer_lock_t) EXCLUDES(mu) : mut(mu), locked(false) {}
976
977    // Same as constructors, but without tag types. (Requires C++17 copy elision.)
978    static MutexLocker Lock(Mutex *mu) ACQUIRE(mu) {
979      return MutexLocker(mu);
980    }
981
982    static MutexLocker Adopt(Mutex *mu) REQUIRES(mu) {
983      return MutexLocker(mu, adopt_lock);
984    }
985
986    static MutexLocker ReaderLock(Mutex *mu) ACQUIRE_SHARED(mu) {
987      return MutexLocker(mu, shared_lock);
988    }
989
990    static MutexLocker AdoptReaderLock(Mutex *mu) REQUIRES_SHARED(mu) {
991      return MutexLocker(mu, adopt_lock, shared_lock);
992    }
993
994    static MutexLocker DeferLock(Mutex *mu) EXCLUDES(mu) {
995      return MutexLocker(mu, defer_lock);
996    }
997
998    // Release *this and all associated mutexes, if they are still held.
999    // There is no warning if the scope was already unlocked before.
1000    ~MutexLocker() RELEASE() {
1001      if (locked)
1002        mut->GenericUnlock();
1003    }
1004
1005    // Acquire all associated mutexes exclusively.
1006    void Lock() ACQUIRE() {
1007      mut->Lock();
1008      locked = true;
1009    }
1010
1011    // Try to acquire all associated mutexes exclusively.
1012    bool TryLock() TRY_ACQUIRE(true) {
1013      return locked = mut->TryLock();
1014    }
1015
1016    // Acquire all associated mutexes in shared mode.
1017    void ReaderLock() ACQUIRE_SHARED() {
1018      mut->ReaderLock();
1019      locked = true;
1020    }
1021
1022    // Try to acquire all associated mutexes in shared mode.
1023    bool ReaderTryLock() TRY_ACQUIRE_SHARED(true) {
1024      return locked = mut->ReaderTryLock();
1025    }
1026
1027    // Release all associated mutexes. Warn on double unlock.
1028    void Unlock() RELEASE() {
1029      mut->Unlock();
1030      locked = false;
1031    }
1032
1033    // Release all associated mutexes. Warn on double unlock.
1034    void ReaderUnlock() RELEASE() {
1035      mut->ReaderUnlock();
1036      locked = false;
1037    }
1038  };
1039
1040
1041  #ifdef USE_LOCK_STYLE_THREAD_SAFETY_ATTRIBUTES
1042  // The original version of thread safety analysis the following attribute
1043  // definitions.  These use a lock-based terminology.  They are still in use
1044  // by existing thread safety code, and will continue to be supported.
1045
1046  // Deprecated.
1047  #define PT_GUARDED_VAR \
1048    THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_var)
1049
1050  // Deprecated.
1051  #define GUARDED_VAR \
1052    THREAD_ANNOTATION_ATTRIBUTE__(guarded_var)
1053
1054  // Replaced by REQUIRES
1055  #define EXCLUSIVE_LOCKS_REQUIRED(...) \
1056    THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(__VA_ARGS__))
1057
1058  // Replaced by REQUIRES_SHARED
1059  #define SHARED_LOCKS_REQUIRED(...) \
1060    THREAD_ANNOTATION_ATTRIBUTE__(shared_locks_required(__VA_ARGS__))
1061
1062  // Replaced by CAPABILITY
1063  #define LOCKABLE \
1064    THREAD_ANNOTATION_ATTRIBUTE__(lockable)
1065
1066  // Replaced by SCOPED_CAPABILITY
1067  #define SCOPED_LOCKABLE \
1068    THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
1069
1070  // Replaced by ACQUIRE
1071  #define EXCLUSIVE_LOCK_FUNCTION(...) \
1072    THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__))
1073
1074  // Replaced by ACQUIRE_SHARED
1075  #define SHARED_LOCK_FUNCTION(...) \
1076    THREAD_ANNOTATION_ATTRIBUTE__(shared_lock_function(__VA_ARGS__))
1077
1078  // Replaced by RELEASE and RELEASE_SHARED
1079  #define UNLOCK_FUNCTION(...) \
1080    THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__))
1081
1082  // Replaced by TRY_ACQUIRE
1083  #define EXCLUSIVE_TRYLOCK_FUNCTION(...) \
1084    THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__))
1085
1086  // Replaced by TRY_ACQUIRE_SHARED
1087  #define SHARED_TRYLOCK_FUNCTION(...) \
1088    THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock_function(__VA_ARGS__))
1089
1090  // Replaced by ASSERT_CAPABILITY
1091  #define ASSERT_EXCLUSIVE_LOCK(...) \
1092    THREAD_ANNOTATION_ATTRIBUTE__(assert_exclusive_lock(__VA_ARGS__))
1093
1094  // Replaced by ASSERT_SHARED_CAPABILITY
1095  #define ASSERT_SHARED_LOCK(...) \
1096    THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_lock(__VA_ARGS__))
1097
1098  // Replaced by EXCLUDE_CAPABILITY.
1099  #define LOCKS_EXCLUDED(...) \
1100    THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
1101
1102  // Replaced by RETURN_CAPABILITY
1103  #define LOCK_RETURNED(x) \
1104    THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
1105
1106  #endif  // USE_LOCK_STYLE_THREAD_SAFETY_ATTRIBUTES
1107
1108  #endif  // THREAD_SAFETY_ANALYSIS_MUTEX_H
1109