John Jones
John Jones

Reputation: 43

Clang++ SCOPED_CAPABILITY produces "warning: releasing mutex 'locker' that was not held"

After attempting to implement the necessary annotations to an existing codebase, I was unable to remove a seemingly simple warning. I backed into the most simple example, and still no joy.

I have cut-and-pasted the mutex.h header exactly as specified at Thread Safety Analysis. I cannot seem to do a scoped lock without producing a warning. Here is the code:

#include "mutex.h"

#include <iostream>

// functions added just to complete the implementation
void Mutex::Lock()
{
}
void Mutex::GenericUnlock()
{
}

// test a scoped lock
void do_something(Mutex &m)
{
    auto locker = MutexLocker(&m);
    std::cout << "Hello, world!\n";
}

int main(int argc, char** argv)
{
    Mutex my_mutex;
    do_something(my_mutex);
}

Compiling with clang++ -o thread_static_analysis thread_static_analysis.cpp -std=c++17 -Wthread-safety produces the following warning:

thread_static_analysis.cpp:18:1: warning: releasing mutex 'locker' that was not held [-Wthread-safety-analysis]
}
^
1 warning generated.

Either (1) I am missing something, or (2) this is a false-positive that must be ignored until a clang implementation issue is resolved. A search for such issues has as-yet given no useful results.

clang version 10.0.0-4ubuntu1 
Target: x86_64-pc-linux-gnu
Thread model: posix

Upvotes: 0

Views: 499

Answers (1)

yugr
yugr

Reputation: 21954

My understanding is that you are potentially creating a copy of temporary MutexLocker object in

auto locker = MutexLocker(&m);

(or thread safety analysis thinks you are creating it). The temporary is then destroyed and calls m.Unlock(). Then at the end of the function the locker object is destroyed and calls m.Unlock() again (thus causing a double release error).

Upvotes: 1

Related Questions