[cfe-dev] Strange "release_shared_capability" behavior in Clang thread safety analysis

Jason Henline via cfe-dev cfe-dev at lists.llvm.org
Fri Jul 29 10:29:30 PDT 2016


While experimenting with Clang's thread safety analysis (
http://clang.llvm.org/docs/ThreadSafetyAnalysis.html) I ran into a compiler
warning I didn't understand. It seems that the release_shared_capability
attribute is not doing what I expect. The code to reproduce is below:

// Begin file: getvalue.cc
// Fake mutex class.
class __attribute__((capability("mutex"))) mutex {
public:
  void SharedLock() __attribute__((acquire_shared_capability())) {
    // Do nothing for this fake mutex.
  }
  void SharedUnlock() __attribute__((release_shared_capability())) {
    // Do nothing for this fake mutex.
  }
};

// Scoped lock class to do RAII locking for the fake mutex class above.
class __attribute__((scoped_lockable)) mutex_lock {
public:
  mutex_lock(mutex *Mutex) __attribute__((acquire_shared_capability(Mutex)))
  : Mutex(Mutex) {
    Mutex->SharedLock();
  }
  ~mutex_lock() __attribute__((release_shared_capability())) {
    Mutex->SharedUnlock();
  }

private:
  mutex *Mutex;
};

// Global mutex and a corresponding value for it to protect.
mutex Mutex;
int Value __attribute__((guarded_by(Mutex))) = 42;

// Explicitly lock and unlock the mutex to read the value.
int getValueExplicitUnlock() {
  Mutex.SharedLock();
  int LocalValue = Value;
  Mutex.SharedUnlock();
  return LocalValue;
}

// Use the scoped lock class to lock and unlock the mutex.
// This is where the problem happens.
int getValueScopedLock() {
  mutex_lock Lock(&Mutex);
  return Value;
}
// End file: getvalue.cc

Compiling with tip-of-tree clang with the -Wthread-safety flag, I get the
following warning:

# Begin shell session
$ clang++ -Wthread-safety -c getvalue.cc
getvalue.cc:37:10: warning: releasing mutex 'Lock' using shared access,
expected exclusive access
      [-Wthread-safety-analysis]
  return Value;
         ^
1 warning generated.
# End shell session

So there is a problem with my scoped lock in the getValueScopedLock
function, but there is no problem with the explicit locking and unlocking
in my getValueExplicitUnlock function.

The warning goes away if I switch the annotation on the ~mutex_lock
destructor to "release_capability" instead of "release_shared_capability".
Is this the expected behavior? It seems like an "acquire_shared_capability"
should be paired with a "release_shared_capability".

I also found a stack overflow question where someone else ran into this
problem:
http://stackoverflow.com/questions/33608378/clang-thread-safety-annotation-and-shared-capabilities
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20160729/107969c9/attachment.html>


More information about the cfe-dev mailing list