title: Clang thread safety annotation and shared capabilities
body: <p>The following code is generating one warning when I use clang <a href="http://clang.llvm.org/docs/ThreadSafetyAnalysis.html" rel="nofollow">thread annotations</a>. I am trying to wrap <code>boost::shared_mutex</code> and <code>boost::shared_lock</code>. How can I express that this lock is a shared lock using the thread annotations?</p>
  
  <p><strong>source code:</strong></p>
  
  <pre class="lang-cpp prettyprint-override"><code>#include &lt;mutex&gt;
  #include "boost/thread/shared_mutex.hpp"
  
  class __attribute__((shared_capability("mutex"))) BoostSharedMutex {
  public:
    boost::shared_mutex &amp;getNativeHandle() { return m_mutex; }
  private:
    mutable boost::shared_mutex m_mutex;
  };
  
  class __attribute__((scoped_lockable)) MutexSharedLock {
  public:
      explicit MutexSharedLock(BoostSharedMutex &amp;mutex) __attribute__((acquire_shared_capability(mutex)))
          : m_lock(mutex.getNativeHandle()) {}
      ~MutexSharedLock() __attribute__((release_shared_capability())) = default;
  
  private:
      boost::shared_lock&lt;boost::shared_mutex&gt; m_lock;
  };
  
  
  int main() {
    BoostSharedMutex mutex;
    MutexSharedLock lock(mutex);
  }
  </code></pre>
  
  <p><strong>clang output:</strong></p>
  
  <pre><code>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.
  </code></pre>
  
  <p>EDIT: this compiles but seems wrong. Is it a problem on my side?</p>
  
  <pre><code>#include &lt;mutex&gt;
  #include "boost/thread/shared_mutex.hpp"
  
  class __attribute__((shared_capability("mutex"))) BoostSharedMutex {
  public:
    boost::shared_mutex &amp;getNativeHandle() { return m_mutex; }
  private:
    mutable boost::shared_mutex m_mutex;
  };
  
  class __attribute__((scoped_lockable)) MutexSharedLock {
  public:
      explicit MutexSharedLock(BoostSharedMutex &amp;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&lt;boost::shared_mutex&gt; m_lock;
  };
  
  BoostSharedMutex mutex;
  int locked_variable __attribute__((guarded_by(mutex)));
  
  int main() {
    MutexSharedLock lock(mutex);
    std::cout &lt;&lt; locked_variable &lt;&lt; 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?
  }
  </code></pre>