Skip to content

False positive on unix.BlockInCriticalSection: not checking destructors #165528

@halfgaar

Description

@halfgaar

False positive on unix.BlockInCriticalSection; it doesn't see destructors that unlock locks.

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>

int main()
{

  int fd = eventfd(0, EFD_NONBLOCK);
  std::mutex m;

  while (true)
  {
   // This lock gets yielded, but unix.BlockInCriticalSection doesn't see it
    std::unique_lock ul(m); 

    uint64_t eventfd_value = 0;
    if (read(fd, &eventfd_value, sizeof(uint64_t)) < 0)
      return 1;

  }

  return 0;

}

Error:

$HOME/opt/Qt/Tools/QtCreator/libexec/qtcreator/clang/bin/clang-tidy -p /tmp/QtCreator-HakOdJ/ClazyWINiRx/compile_commands.json -checks=-*,clang-analyzer-unix.BlockInCriticalSection main.cpp
/home/halfgaar/tmp/block/main.cpp:15:9: warning: Call to blocking function 'read' inside of critical section [clang-analyzer-unix.BlockInCriticalSection]
   15 |     if (read(fd, &eventfd_value, sizeof(uint64_t)) < 0)
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/halfgaar/tmp/block/main.cpp:11:3: note: Loop condition is true.  Entering loop body
   11 |   while (true)
      |   ^
/home/halfgaar/tmp/block/main.cpp:13:22: note: Calling constructor for 'unique_lock<std::mutex>'
   13 |     std::unique_lock ul(m);
      |                      ^~~~~
/usr/include/c++/11/bits/unique_lock.h:69:2: note: Calling 'unique_lock::lock'
   69 |         lock();
      |         ^~~~~~
/usr/include/c++/11/bits/unique_lock.h:133:7: note: Field '_M_device' is non-null
  133 |         if (!_M_device)
      |              ^
/usr/include/c++/11/bits/unique_lock.h:133:2: note: Taking false branch
  133 |         if (!_M_device)
      |         ^
/usr/include/c++/11/bits/unique_lock.h:135:11: note: Field '_M_owns' is false
  135 |         else if (_M_owns)
      |                  ^
/usr/include/c++/11/bits/unique_lock.h:135:7: note: Taking false branch
  135 |         else if (_M_owns)
      |              ^
/usr/include/c++/11/bits/unique_lock.h:139:6: note: Calling 'mutex::lock'
  139 |             _M_device->lock();
      |             ^~~~~~~~~~~~~~~~~
/usr/include/c++/11/bits/std_mutex.h:100:17: note: Calling '__gthread_mutex_lock'
  100 |       int __e = __gthread_mutex_lock(&_M_mutex);
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/x86_64-linux-gnu/c++/11/bits/gthr-default.h:748:3: note: Taking true branch
  748 |   if (__gthread_active_p ())
      |   ^
/usr/include/x86_64-linux-gnu/c++/11/bits/gthr-default.h:749:21: note: Entering critical section here
  749 |     return __gthrw_(pthread_mutex_lock) (__mutex);
      |                     ^
/usr/include/x86_64-linux-gnu/c++/11/bits/gthr-default.h:96:25: note: expanded from macro '__gthrw_'
   96 | # define __gthrw_(name) name
      |                         ^
/usr/include/c++/11/bits/std_mutex.h:100:17: note: Returning from '__gthread_mutex_lock'
  100 |       int __e = __gthread_mutex_lock(&_M_mutex);
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/11/bits/std_mutex.h:103:11: note: Assuming '__e' is 0
  103 |       if (__e)
      |           ^~~
/usr/include/c++/11/bits/std_mutex.h:103:7: note: Taking false branch
  103 |       if (__e)
      |       ^
/usr/include/c++/11/bits/unique_lock.h:139:6: note: Returning from 'mutex::lock'
  139 |             _M_device->lock();
      |             ^~~~~~~~~~~~~~~~~
/usr/include/c++/11/bits/unique_lock.h:139:6: note: Entering critical section here
  139 |             _M_device->lock();
      |             ^~~~~~~~~~~~~~~~~
/usr/include/c++/11/bits/unique_lock.h:69:2: note: Returning from 'unique_lock::lock'
   69 |         lock();
      |         ^~~~~~
/usr/include/c++/11/bits/unique_lock.h:69:2: note: Entering critical section for the 1st time here
   69 |         lock();
      |         ^~~~~~
/home/halfgaar/tmp/block/main.cpp:13:22: note: Returning from constructor for 'unique_lock<std::mutex>'
   13 |     std::unique_lock ul(m);
      |                      ^~~~~
/home/halfgaar/tmp/block/main.cpp:13:22: note: Entering critical section for the 2nd time here
   13 |     std::unique_lock ul(m);
      |                      ^~~~~
/home/halfgaar/tmp/block/main.cpp:15:9: note: Call to blocking function 'read' inside of critical section
   15 |     if (read(fd, &eventfd_value, sizeof(uint64_t)) < 0)
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:static analyzerfalse-positiveWarning fires when it should notquestionA question, not bug report. Check out https://llvm.org/docs/GettingInvolved.html instead!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions