| Issue |
175309
|
| Summary |
False positive on unix.BlockInCriticalSection: not checked through templates
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
halfgaar
|
False positive on `unix.BlockInCriticalSection`. It doesn't seem to track it through templates.
Version:
```
$HOME/opt/Qt/Tools/QtCreator/libexec/qtcreator/clang/bin/clang-tidy --version
LLVM (http://llvm.org/):
LLVM version 20.1.3
Optimized build.
```
Repro:
```
#include <unistd.h>
#include <sys/eventfd.h>
#include <mutex>
#include <vector>
#include <iostream>
#include <thread>
template<typename T>
class MutexLocked
{
std::unique_lock<std::mutex> l;
T *d = nullptr;
public:
MutexLocked() = default;
MutexLocked(T &other, std::mutex &m) :
l(m),
d(&other)
{
}
MutexLocked(const MutexLocked<T> &other) = delete;
MutexLocked<T> &operator=(const MutexLocked<T> &other) = delete;
MutexLocked(MutexLocked<T> &&other) noexcept :
l(std::move(other.l)),
d(other.d)
{
other.d = nullptr;
}
~MutexLocked()
{
std::cout << "Destroying MutexLocked, which destroys the unique_lock" << std::endl;
d = nullptr;
}
};
template<typename T>
class MutexOwned
{
std::mutex m;
T d;
public:
template<typename... Args>
MutexOwned(Args... args) :
d(args...)
{
}
MutexLocked<T> lock()
{
MutexLocked<T> r(d, m);
return r;
}
};
int main()
{
int fd = eventfd(0, EFD_NONBLOCK);
MutexOwned<std::vector<std::string>> strings;
while (true)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
uint64_t eventfd_value = 0;
if (read(fd, &eventfd_value, sizeof(uint64_t)) < 0)
std::cout << "No event written to eventfd, but that's OK" << std::endl;
{
auto locked = strings.lock();
continue;
}
if (read(fd, &eventfd_value, sizeof(uint64_t)) < 0)
std::cout << "No event written to eventfd, but that's OK" << std::endl;
}
return 0;
}
```
Result:
```
$ /home/halfgaar/opt/Qt/Tools/QtCreator/libexec/qtcreator/clang/bin/clang-tidy -p /tmp/QtCreator-UcKgAx/Clang-TidylIJEDJ/compile_commands.json main.cpp
1 warning generated.
/home/halfgaar/tmp/clang_false_postive/main.cpp:75:13: warning: Call to blocking function 'read' inside of critical section [clang-analyzer-unix.BlockInCriticalSection]
75 | if (read(fd, &eventfd_value, sizeof(uint64_t)) < 0)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/halfgaar/tmp/clang_false_postive/main.cpp:70:5: note: Loop condition is true. Entering loop body
70 | while (true)
| ^
/home/halfgaar/tmp/clang_false_postive/main.cpp:75:13: note: Assuming the condition is false
75 | if (read(fd, &eventfd_value, sizeof(uint64_t)) < 0)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/halfgaar/tmp/clang_false_postive/main.cpp:75:9: note: Taking false branch
75 | if (read(fd, &eventfd_value, sizeof(uint64_t)) < 0)
| ^
/home/halfgaar/tmp/clang_false_postive/main.cpp:79:27: note: Calling 'MutexOwned::lock'
79 | auto locked = strings.lock();
| ^~~~~~~~~~~~~~
/home/halfgaar/tmp/clang_false_postive/main.cpp:59:24: note: Calling constructor for 'MutexLocked<std::vector<std::basic_string<char>>>'
59 | MutexLocked<T> r(d, m);
| ^~~~~~~
/home/halfgaar/tmp/clang_false_postive/main.cpp:19:9: note: Calling constructor for 'unique_lock<std::mutex>'
19 | l(m),
| ^~~~
/usr/include/c++/11/bits/unique_lock.h:69:2: note: Entering critical section here
69 | lock();
| ^~~~~~
/home/halfgaar/tmp/clang_false_postive/main.cpp:19:9: note: Returning from constructor for 'unique_lock<std::mutex>'
19 | l(m),
| ^~~~
/home/halfgaar/tmp/clang_false_postive/main.cpp:59:24: note: Returning from constructor for 'MutexLocked<std::vector<std::basic_string<char>>>'
59 | MutexLocked<T> r(d, m);
| ^~~~~~~
/home/halfgaar/tmp/clang_false_postive/main.cpp:79:27: note: Returning from 'MutexOwned::lock'
79 | auto locked = strings.lock();
| ^~~~~~~~~~~~~~
/home/halfgaar/tmp/clang_false_postive/main.cpp:80:13: note: Execution continues on line 70
80 | continue;
| ^
/home/halfgaar/tmp/clang_false_postive/main.cpp:70:5: note: Loop condition is true. Entering loop body
70 | while (true)
| ^
/home/halfgaar/tmp/clang_false_postive/main.cpp:75:13: note: Call to blocking function 'read' inside of critical section
75 | if (read(fd, &eventfd_value, sizeof(uint64_t)) < 0)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs