llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
26.71k stars 10.94k forks source link

clang-analyzer-cplusplus.NewDeleteLeaks false positive #47628

Open firewave opened 3 years ago

firewave commented 3 years ago
Bugzilla Link 48284
Version unspecified
OS Windows NT
CC @devincoughlin,@EugeneZelenko

Extended Description

#include <functional>

class A
{
public:
  A() = default;

  A(const A& other)
  {
    std::copy(other.raw_, other.raw_ + 8, raw_);
  }

private:
  char raw_[8];
};

class P
{
public:
  class T
  {
  public:
    T(std::function<void()> h, A a)
      : h_(std::move(h))
      , a_{std::move(a)}
    {
    }

    std::function<void()> h_;
    A a_;
  };

  static void f(std::function<void()> h, const A& a)
  {
    (void)T(std::move(h), a);
  }
};

static void func()
{
  A a;
  P::f([a]() {}, a);
}

clang-tidy output:

/mnt/c/_temp/memleak-fp.cpp:11:3: warning: Potential memory leak [clang-analyzer-cplusplus.NewDeleteLeaks]
  }
  ^
/mnt/c/_temp/memleak-fp.cpp:42:8: note: Calling constructor for 'function<void ()>'
  P::f([a]() {}, a);
       ^
/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/std_function.h:607:2: note: Taking true branch
        if (_My_handler::_M_not_empty_function(__f))
        ^
/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/std_function.h:609:6: note: Calling '_Base_manager::_M_init_functor'
            _My_handler::_M_init_functor(_M_functor, std::move(__f));
            ^
/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/std_function.h:208:4: note: Calling '_Base_manager::_M_init_functor'
        { _M_init_functor(__functor, std::move(__f), _Local_storage()); }
          ^
/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/std_function.h:237:39: note: Memory is allocated
        { __functor._M_access<_Functor*>() = new _Functor(std::move(__f)); }
                                             ^
/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/std_function.h:208:4: note: Returned allocated memory
        { _M_init_functor(__functor, std::move(__f), _Local_storage()); }
          ^
/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/std_function.h:609:6: note: Returned allocated memory
            _My_handler::_M_init_functor(_M_functor, std::move(__f));
            ^
/mnt/c/_temp/memleak-fp.cpp:42:8: note: Returning from constructor for 'function<void ()>'
  P::f([a]() {}, a);
       ^
/mnt/c/_temp/memleak-fp.cpp:42:3: note: Calling 'P::f'
  P::f([a]() {}, a);
  ^
/mnt/c/_temp/memleak-fp.cpp:35:11: note: Calling constructor for 'T'
    (void)T(std::move(h), a);
          ^
/mnt/c/_temp/memleak-fp.cpp:25:9: note: Calling copy constructor for 'A'
      , a_{std::move(a)}
        ^
/mnt/c/_temp/memleak-fp.cpp:11:3: note: Potential memory leak
  }
  ^

If you remove the std::copy() call or any of the "h" or "a" parameters the warning goes away.

This has been greatly reduced from the original case this was reported for.

firewave commented 3 years ago

assigned to @devincoughlin