llvm / llvm/llvm-project

-Wthread-safety-reference warnings and -Weverything

Open
#210,307 0 comments 0 reactions 0 assignees View on GitHub
clang:diagnostics
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

I get some `-Wthread-safety-reference` warnings only when `-Weverything` has been activated.

Example:

```c++
#include

#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
#define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
#define DECL_VAR_GUARDED_BY(m, ...) __VA_ARGS__ GUARDED_BY(m)

template
class MutexedObj {
mutable mutex m;
DECL_VAR_GUARDED_BY(m, T obj);

public:
template
constexpr explicit MutexedObj(Args&&... args) noexcept(
std::is_nothrow_constructible_v)
: obj(std::forward(args)...) {}

//! Use the free function lock to access the protected data
template
friend decltype(auto) lock(const MutexedObj& mo, F f) {
std::lock_guard l(mo.m);
return f(mo.obj);
}

template
friend decltype(auto) lock(MutexedObj& mo, F f) {
std::lock_guard l(mo.m);
return f(mo.obj);
}
};

constinit auto data = MutexedObj();

void foo(int i);
void foo(int i) {
lock(data, [&](int& j) { j = i; });
}
```

Compile it with `--std=c++20 -Wthread-safety-reference`: there are no warnings.
Compile it with `--std=c++20 -Weverything -Wno-reserved-macro-identifier -Wno-c++98-compat-pedantic -Wno-padded -Wno-missing-variable-declarations`, clang outputs

```
:28:21: warning: passing variable 'obj' by reference requires holding mutex 'mo.m' [-Wthread-safety-reference]
28 | return f(mo.obj);
| ^
:36:5: note: in instantiation of function template specialization 'lock<(lambda at :36:16)>' requested here
36 | lock(data, [&](int& j) { j = i; });
| ^
:26:63: note: thread warning in function 'lock<(lambda at :36:16)>'
26 | friend decltype(auto) lock(MutexedObj& mo, F f) {
```

There are thus two issues.
The first one is the inconsistency between -Weverything triggering -Wthread-safety-reference, but -Wthread-safety-reference not firing by itself.

The second is that the warning is wrong.
`mo.obj` is accessed only after `mo.m` has been locked, as the warning suggests.

Example on godbolt: https://compiler-explorer.com/z/s33EKsEjc

Contributor guide

Open the contributing guide

Research direction

Start with the provided C++20 reproducer and the Compiler Explorer example, comparing standalone -Wthread-safety-reference with -Weverything. Investigate why the warning is enabled inconsistently and why the locked mo.obj access is reported; done means both warning behaviors are corrected for this reproducer.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.