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

Reply via email to