Q: Clang thread safety annotation and shared capabilities The following code is generating one warning when I use clang thread annotations. I am trying to wrap boost::shared_mutex and boost::shared_lock. How can I express that this lock is a shared lock using the thread annotations?
source code:
#include <mutex>
#include "boost/thread/shared_mutex.hpp"

class __attribute__((shared_capability("mutex"))) BoostSharedMutex {
public:
  boost::shared_mutex &getNativeHandle() { return m_mutex; }
private:
  mutable boost::shared_mutex m_mutex;
};

class __attribute__((scoped_lockable)) MutexSharedLock {
public:
    explicit MutexSharedLock(BoostSharedMutex &mutex) __attribute__((acquire_shared_capability(mutex)))
        : m_lock(mutex.getNativeHandle()) {}
    ~MutexSharedLock() __attribute__((release_shared_capability())) = default;

private:
    boost::shared_lock<boost::shared_mutex> m_lock;
};


int main() {
  BoostSharedMutex mutex;
  MutexSharedLock lock(mutex);
}

clang output:
clang++-3.6 --std=c++11 -Wall -Wthread-safety /tmp/foo.cpp -lboost_system
/tmp/foo.cpp:25:5: warning: releasing mutex 'lock' using shared access, expected exclusive access [-Wthread-safety-analysis]
    }
    ^
1 warning generated.

EDIT: this compiles but seems wrong. Is it a problem on my side?
#include <mutex>
#include "boost/thread/shared_mutex.hpp"

class __attribute__((shared_capability("mutex"))) BoostSharedMutex {
public:
  boost::shared_mutex &getNativeHandle() { return m_mutex; }
private:
  mutable boost::shared_mutex m_mutex;
};

class __attribute__((scoped_lockable)) MutexSharedLock {
public:
    explicit MutexSharedLock(BoostSharedMutex &mutex) __attribute__((acquire_capability(mutex))) // changed  from acquired_shared_capability
        : m_lock(mutex.getNativeHandle()) {}
    ~MutexSharedLock() __attribute__((release_capability())) = default; // changed from release_shared_capability

private:
    boost::shared_lock<boost::shared_mutex> m_lock;
};

BoostSharedMutex mutex;
int locked_variable __attribute__((guarded_by(mutex)));

int main() {
  MutexSharedLock lock(mutex);
  std::cout << locked_variable << std::endl; // ok, guarded variable is only read
  locked_variable = 42; // no warning while writing in the guarded variable while only holding a non-exclusive lock?
}


A: After trying several combinations, this seems to work:
#include <mutex>
#include "boost/thread/shared_mutex.hpp"

class __attribute__((capability("mutex"))) BoostSharedMutex {
public:
  boost::shared_mutex &getNativeHandle() { return m_mutex; }
private:
  mutable boost::shared_mutex m_mutex;
};

class __attribute__((scoped_lockable)) MutexSharedLock {
public:
    explicit MutexSharedLock(BoostSharedMutex &mutex) __attribute__((acquire_shared_capability(mutex)))
        : m_lock(mutex.getNativeHandle()) {}
    ~MutexSharedLock() __attribute__((release_capability())) = default;

private:
    boost::shared_lock<boost::shared_mutex> m_lock;
};

class __attribute__((scoped_lockable)) MutexLock {
public:
    explicit MutexLock(BoostSharedMutex &mutex) __attribute__((acquire_capability(mutex)))
        : m_lock(mutex.getNativeHandle()) {}
    ~MutexLock() __attribute__((release_capability())) = default;

private:
    std::unique_lock<boost::shared_mutex> m_lock;
};

BoostSharedMutex mutex;
int locked_variable __attribute__((guarded_by(mutex)));

int main() {
  {
    MutexSharedLock lock(mutex);
    std::cout << locked_variable << std::endl;
    // locked_variable = 42; -- triger a error as expected
  }
  {
    MutexLock lock(mutex);
    std::cout << locked_variable << std::endl;
    locked_variable = 42;
  }
}

I would be curious to hear why the MutexSharedLock should use acquire_shared_capability but release with release_capability ...
(I will let the question open in case anyone can confirm the code is correct now)

A: Just use unlock_function instead of release_shared_capability.
Same true also for try_acquire_capability/try_acquire_shared_capability - they just don't work, but previous exclusive_trylock_function/shared_trylock_function works well.
M.b. it is bug in clang.
