[libc++] thread safety annotations for unique_lock

Hi everyone,

this is my first post to this list, so please remind me if I’m violating your netiquette in some way.

I’m trying to introduce the thread safety analysis to one of our projects and stumble upon the missing thread safety annotations for unique_lock. I thought this might be easy, so let’s provide a patch. But now I’m stuck with correctly annotating the move constructor and the lock() and unlock() methods of unique_lock.

Here is a very basic implementation of my annotated unique_lock:

class SCOPED_CAPABILITY unique_lock {
  ::bluebox::mutex *mu;
  bool lock_held;
public:
  unique_lock() = delete;
  unique_lock(unique_lock &&) = delete; // We cannot annotate move semantics

  explicit unique_lock(::bluebox::mutex &m) ACQUIRE(m) : mu(&m), lock_held(true) { m.lock(); }
  explicit unique_lock(::bluebox::mutex *m) ACQUIRE(m) : mu(m), lock_held(true) { m->lock(); }

  void unlock() RELEASE(mu) NO_THREAD_SAFETY_ANALYSIS {
    if (lock_held) {
      lock_held = false;
      mu->unlock();
    }
  }

  void lock() ACQUIRE(mu) NO_THREAD_SAFETY_ANALYSIS {
    if (!lock_held) {
      mu->lock();
      lock_held = true;
    }
  }

  ~unique_lock() RELEASE() NO_THREAD_SAFETY_ANALYSIS {
    if (lock_held)
      mu->unlock();
  }
};

And this is my test case:

static std::mutex mtx;
void someFunction() {
  my::unique_lock lock(mtx);
  // … Here you would normally do something meaningful
  lock.unlock();
  // … Call a method that might modify your protected data
  lock.lock();
  // … Continue with super important work
}

And here is my list of issues I can’t get around with:
1. How can I correctly annotate the unlock and lock methods? When using unlock() in the above example, clang throws this error: fatal error: releasing mutex
      'lock.mu' that was not held [-Wthread-safety-analysis]
2. How can I correctly annotate the move constructor of unique_lock?