Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- ThreadSafety.h -------------------------------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. //
  10. // A intra-procedural analysis for thread safety (e.g. deadlocks and race
  11. // conditions), based off of an annotation system.
  12. //
  13. // See http://clang.llvm.org/docs/LanguageExtensions.html#thread-safety-annotation-checking
  14. // for more information.
  15. //
  16. //===----------------------------------------------------------------------===//
  17.  
  18. #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETY_H
  19. #define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETY_H
  20.  
  21. #include "clang/Basic/SourceLocation.h"
  22. #include "llvm/ADT/StringRef.h"
  23.  
  24. namespace clang {
  25.  
  26. class AnalysisDeclContext;
  27. class FunctionDecl;
  28. class NamedDecl;
  29.  
  30. namespace threadSafety {
  31.  
  32. class BeforeSet;
  33.  
  34. /// This enum distinguishes between different kinds of operations that may
  35. /// need to be protected by locks. We use this enum in error handling.
  36. enum ProtectedOperationKind {
  37.   /// Dereferencing a variable (e.g. p in *p = 5;)
  38.   POK_VarDereference,
  39.  
  40.   /// Reading or writing a variable (e.g. x in x = 5;)
  41.   POK_VarAccess,
  42.  
  43.   /// Making a function call (e.g. fool())
  44.   POK_FunctionCall,
  45.  
  46.   /// Passing a guarded variable by reference.
  47.   POK_PassByRef,
  48.  
  49.   /// Passing a pt-guarded variable by reference.
  50.   POK_PtPassByRef
  51. };
  52.  
  53. /// This enum distinguishes between different kinds of lock actions. For
  54. /// example, it is an error to write a variable protected by shared version of a
  55. /// mutex.
  56. enum LockKind {
  57.   /// Shared/reader lock of a mutex.
  58.   LK_Shared,
  59.  
  60.   /// Exclusive/writer lock of a mutex.
  61.   LK_Exclusive,
  62.  
  63.   /// Can be either Shared or Exclusive.
  64.   LK_Generic
  65. };
  66.  
  67. /// This enum distinguishes between different ways to access (read or write) a
  68. /// variable.
  69. enum AccessKind {
  70.   /// Reading a variable.
  71.   AK_Read,
  72.  
  73.   /// Writing a variable.
  74.   AK_Written
  75. };
  76.  
  77. /// This enum distinguishes between different situations where we warn due to
  78. /// inconsistent locking.
  79. /// \enum SK_LockedSomeLoopIterations -- a mutex is locked for some but not all
  80. /// loop iterations.
  81. /// \enum SK_LockedSomePredecessors -- a mutex is locked in some but not all
  82. /// predecessors of a CFGBlock.
  83. /// \enum SK_LockedAtEndOfFunction -- a mutex is still locked at the end of a
  84. /// function.
  85. enum LockErrorKind {
  86.   LEK_LockedSomeLoopIterations,
  87.   LEK_LockedSomePredecessors,
  88.   LEK_LockedAtEndOfFunction,
  89.   LEK_NotLockedAtEndOfFunction
  90. };
  91.  
  92. /// Handler class for thread safety warnings.
  93. class ThreadSafetyHandler {
  94. public:
  95.   using Name = StringRef;
  96.  
  97.   ThreadSafetyHandler() = default;
  98.   virtual ~ThreadSafetyHandler();
  99.  
  100.   /// Warn about lock expressions which fail to resolve to lockable objects.
  101.   /// \param Loc -- the SourceLocation of the unresolved expression.
  102.   virtual void handleInvalidLockExp(SourceLocation Loc) {}
  103.  
  104.   /// Warn about unlock function calls that do not have a prior matching lock
  105.   /// expression.
  106.   /// \param Kind -- the capability's name parameter (role, mutex, etc).
  107.   /// \param LockName -- A StringRef name for the lock expression, to be printed
  108.   /// in the error message.
  109.   /// \param Loc -- The SourceLocation of the Unlock
  110.   /// \param LocPreviousUnlock -- If valid, the location of a previous Unlock.
  111.   virtual void handleUnmatchedUnlock(StringRef Kind, Name LockName,
  112.                                      SourceLocation Loc,
  113.                                      SourceLocation LocPreviousUnlock) {}
  114.  
  115.   /// Warn about an unlock function call that attempts to unlock a lock with
  116.   /// the incorrect lock kind. For instance, a shared lock being unlocked
  117.   /// exclusively, or vice versa.
  118.   /// \param LockName -- A StringRef name for the lock expression, to be printed
  119.   /// in the error message.
  120.   /// \param Kind -- the capability's name parameter (role, mutex, etc).
  121.   /// \param Expected -- the kind of lock expected.
  122.   /// \param Received -- the kind of lock received.
  123.   /// \param LocLocked -- The SourceLocation of the Lock.
  124.   /// \param LocUnlock -- The SourceLocation of the Unlock.
  125.   virtual void handleIncorrectUnlockKind(StringRef Kind, Name LockName,
  126.                                          LockKind Expected, LockKind Received,
  127.                                          SourceLocation LocLocked,
  128.                                          SourceLocation LocUnlock) {}
  129.  
  130.   /// Warn about lock function calls for locks which are already held.
  131.   /// \param Kind -- the capability's name parameter (role, mutex, etc).
  132.   /// \param LockName -- A StringRef name for the lock expression, to be printed
  133.   /// in the error message.
  134.   /// \param LocLocked -- The location of the first lock expression.
  135.   /// \param LocDoubleLock -- The location of the second lock expression.
  136.   virtual void handleDoubleLock(StringRef Kind, Name LockName,
  137.                                 SourceLocation LocLocked,
  138.                                 SourceLocation LocDoubleLock) {}
  139.  
  140.   /// Warn about situations where a mutex is sometimes held and sometimes not.
  141.   /// The three situations are:
  142.   /// 1. a mutex is locked on an "if" branch but not the "else" branch,
  143.   /// 2, or a mutex is only held at the start of some loop iterations,
  144.   /// 3. or when a mutex is locked but not unlocked inside a function.
  145.   /// \param Kind -- the capability's name parameter (role, mutex, etc).
  146.   /// \param LockName -- A StringRef name for the lock expression, to be printed
  147.   /// in the error message.
  148.   /// \param LocLocked -- The location of the lock expression where the mutex is
  149.   ///               locked
  150.   /// \param LocEndOfScope -- The location of the end of the scope where the
  151.   ///               mutex is no longer held
  152.   /// \param LEK -- which of the three above cases we should warn for
  153.   virtual void handleMutexHeldEndOfScope(StringRef Kind, Name LockName,
  154.                                          SourceLocation LocLocked,
  155.                                          SourceLocation LocEndOfScope,
  156.                                          LockErrorKind LEK) {}
  157.  
  158.   /// Warn when a mutex is held exclusively and shared at the same point. For
  159.   /// example, if a mutex is locked exclusively during an if branch and shared
  160.   /// during the else branch.
  161.   /// \param Kind -- the capability's name parameter (role, mutex, etc).
  162.   /// \param LockName -- A StringRef name for the lock expression, to be printed
  163.   /// in the error message.
  164.   /// \param Loc1 -- The location of the first lock expression.
  165.   /// \param Loc2 -- The location of the second lock expression.
  166.   virtual void handleExclusiveAndShared(StringRef Kind, Name LockName,
  167.                                         SourceLocation Loc1,
  168.                                         SourceLocation Loc2) {}
  169.  
  170.   /// Warn when a protected operation occurs while no locks are held.
  171.   /// \param D -- The decl for the protected variable or function
  172.   /// \param POK -- The kind of protected operation (e.g. variable access)
  173.   /// \param AK -- The kind of access (i.e. read or write) that occurred
  174.   /// \param Loc -- The location of the protected operation.
  175.   virtual void handleNoMutexHeld(const NamedDecl *D, ProtectedOperationKind POK,
  176.                                  AccessKind AK, SourceLocation Loc) {}
  177.  
  178.   /// Warn when a protected operation occurs while the specific mutex protecting
  179.   /// the operation is not locked.
  180.   /// \param Kind -- the capability's name parameter (role, mutex, etc).
  181.   /// \param D -- The decl for the protected variable or function
  182.   /// \param POK -- The kind of protected operation (e.g. variable access)
  183.   /// \param LockName -- A StringRef name for the lock expression, to be printed
  184.   /// in the error message.
  185.   /// \param LK -- The kind of access (i.e. read or write) that occurred
  186.   /// \param Loc -- The location of the protected operation.
  187.   virtual void handleMutexNotHeld(StringRef Kind, const NamedDecl *D,
  188.                                   ProtectedOperationKind POK, Name LockName,
  189.                                   LockKind LK, SourceLocation Loc,
  190.                                   Name *PossibleMatch = nullptr) {}
  191.  
  192.   /// Warn when acquiring a lock that the negative capability is not held.
  193.   /// \param Kind -- the capability's name parameter (role, mutex, etc).
  194.   /// \param LockName -- The name for the lock expression, to be printed in the
  195.   /// diagnostic.
  196.   /// \param Neg -- The name of the negative capability to be printed in the
  197.   /// diagnostic.
  198.   /// \param Loc -- The location of the protected operation.
  199.   virtual void handleNegativeNotHeld(StringRef Kind, Name LockName, Name Neg,
  200.                                      SourceLocation Loc) {}
  201.  
  202.   /// Warn when calling a function that a negative capability is not held.
  203.   /// \param D -- The decl for the function requiring the negative capability.
  204.   /// \param LockName -- The name for the lock expression, to be printed in the
  205.   /// diagnostic.
  206.   /// \param Loc -- The location of the protected operation.
  207.   virtual void handleNegativeNotHeld(const NamedDecl *D, Name LockName,
  208.                                      SourceLocation Loc) {}
  209.  
  210.   /// Warn when a function is called while an excluded mutex is locked. For
  211.   /// example, the mutex may be locked inside the function.
  212.   /// \param Kind -- the capability's name parameter (role, mutex, etc).
  213.   /// \param FunName -- The name of the function
  214.   /// \param LockName -- A StringRef name for the lock expression, to be printed
  215.   /// in the error message.
  216.   /// \param Loc -- The location of the function call.
  217.   virtual void handleFunExcludesLock(StringRef Kind, Name FunName,
  218.                                      Name LockName, SourceLocation Loc) {}
  219.  
  220.   /// Warn that L1 cannot be acquired before L2.
  221.   virtual void handleLockAcquiredBefore(StringRef Kind, Name L1Name,
  222.                                         Name L2Name, SourceLocation Loc) {}
  223.  
  224.   /// Warn that there is a cycle in acquired_before/after dependencies.
  225.   virtual void handleBeforeAfterCycle(Name L1Name, SourceLocation Loc) {}
  226.  
  227.   /// Called by the analysis when starting analysis of a function.
  228.   /// Used to issue suggestions for changes to annotations.
  229.   virtual void enterFunction(const FunctionDecl *FD) {}
  230.  
  231.   /// Called by the analysis when finishing analysis of a function.
  232.   virtual void leaveFunction(const FunctionDecl *FD) {}
  233.  
  234.   bool issueBetaWarnings() { return IssueBetaWarnings; }
  235.   void setIssueBetaWarnings(bool b) { IssueBetaWarnings = b; }
  236.  
  237. private:
  238.   bool IssueBetaWarnings = false;
  239. };
  240.  
  241. /// Check a function's CFG for thread-safety violations.
  242. ///
  243. /// We traverse the blocks in the CFG, compute the set of mutexes that are held
  244. /// at the end of each block, and issue warnings for thread safety violations.
  245. /// Each block in the CFG is traversed exactly once.
  246. void runThreadSafetyAnalysis(AnalysisDeclContext &AC,
  247.                              ThreadSafetyHandler &Handler,
  248.                              BeforeSet **Bset);
  249.  
  250. void threadSafetyCleanup(BeforeSet *Cache);
  251.  
  252. /// Helper function that returns a LockKind required for the given level
  253. /// of access.
  254. LockKind getLockKindFromAccessKind(AccessKind AK);
  255.  
  256. } // namespace threadSafety
  257. } // namespace clang
  258.  
  259. #endif // LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETY_H
  260.