[llvm-bugs] [Bug 45514] New: NewDeleteLeaks reports false positive with shared_ptr

via llvm-bugs llvm-bugs at lists.llvm.org
Mon Apr 13 12:11:41 PDT 2020


https://bugs.llvm.org/show_bug.cgi?id=45514

            Bug ID: 45514
           Summary: NewDeleteLeaks reports false positive with shared_ptr
           Product: clang
           Version: unspecified
          Hardware: PC
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: Static Analyzer
          Assignee: dcoughlin at apple.com
          Reporter: pavel.kryukov at phystech.edu
                CC: dcoughlin at apple.com, llvm-bugs at lists.llvm.org

Created attachment 23345
  --> https://bugs.llvm.org/attachment.cgi?id=23345&action=edit
NewDeleteLeaks false positive

In the example attached, memory leak is reported while passing std::shared_ptr
around factory-like methods.

Command line. Note -std=c++17 and -O3 options, without them nothing is reported

> $ clang++-10 --analyze -Xanalyzer -analyzer-output=text -std=c++17 -O3 example.cpp

Output:

example.cpp:26:5: warning: Potential leak of memory pointed to by field '_M_pi'
    return get_D_or_C(config);
    ^
example.cpp:26:12: note: Calling 'get_D_or_C'
    return get_D_or_C(config);
           ^~~~~~~~~~~~~~~~~~
example.cpp:19:12: note: Assuming 'val' is true
    return val ? get_D() : get_C();
           ^~~
example.cpp:19:12: note: '?' condition is true
example.cpp:19:18: note: Calling 'get_D'
    return val ? get_D() : get_C();
                 ^~~~~~~
example.cpp:12:11: note: Calling 'make_shared<D, >'
   return std::make_shared<D>();
          ^~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/shared_ptr.h:721:14:
note: Calling 'allocate_shared<D, std::allocator<D>, >'
      return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(),
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/shared_ptr.h:705:14:
note: Calling constructor for 'shared_ptr<D>'
      return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a},
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/shared_ptr.h:359:4:
note: Calling constructor for '__shared_ptr<D, __gnu_cxx::_S_atomic>'
        : __shared_ptr<_Tp>(__tag, std::forward<_Args>(__args)...)
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/shared_ptr_base.h:1342:14:
note: Calling constructor for '__shared_count<__gnu_cxx::_S_atomic>'
        : _M_ptr(), _M_refcount(_M_ptr, __tag, std::forward<_Args>(__args)...)
                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/shared_ptr_base.h:675:19:
note: Calling
'__allocate_guarded<std::allocator<std::_Sp_counted_ptr_inplace<D,
std::allocator<D>, __gnu_cxx::_S_atomic> >>'
          auto __guard = std::__allocate_guarded(__a2);
                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/allocated_ptr.h:97:21:
note: Calling 'allocator_traits::allocate'
      return { __a, std::allocator_traits<_Alloc>::allocate(__a, 1) };
                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/alloc_traits.h:436:16:
note: Calling 'new_allocator::allocate'
      { return __a.allocate(__n); }
               ^~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/ext/new_allocator.h:101:2:
note: Taking false branch
        if (__n > this->max_size())
        ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/ext/new_allocator.h:105:2:
note: Taking false branch
        if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
        ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/ext/new_allocator.h:111:27:
note: Memory is allocated
        return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/alloc_traits.h:436:16:
note: Returned allocated memory
      { return __a.allocate(__n); }
               ^~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/allocated_ptr.h:97:21:
note: Returned allocated memory
      return { __a, std::allocator_traits<_Alloc>::allocate(__a, 1) };
                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/shared_ptr_base.h:675:19:
note: Returned allocated memory
          auto __guard = std::__allocate_guarded(__a2);
                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/shared_ptr_base.h:1342:14:
note: Returning from constructor for '__shared_count<__gnu_cxx::_S_atomic>'
        : _M_ptr(), _M_refcount(_M_ptr, __tag, std::forward<_Args>(__args)...)
                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/shared_ptr.h:359:4:
note: Returning from constructor for '__shared_ptr<D, __gnu_cxx::_S_atomic>'
        : __shared_ptr<_Tp>(__tag, std::forward<_Args>(__args)...)
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/shared_ptr.h:705:14:
note: Returning from constructor for 'shared_ptr<D>'
      return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a},
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/shared_ptr.h:721:14:
note: Returned allocated memory
      return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(),
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
example.cpp:12:11: note: Returned allocated memory
   return std::make_shared<D>();
          ^~~~~~~~~~~~~~~~~~~~~
example.cpp:19:18: note: Returned allocated memory
    return val ? get_D() : get_C();
                 ^~~~~~~
example.cpp:26:12: note: Returned allocated memory
    return get_D_or_C(config);
           ^~~~~~~~~~~~~~~~~~
example.cpp:26:5: note: Potential leak of memory pointed to by field '_M_pi'
    return get_D_or_C(config);
    ^
1 warning generated.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200413/f44058bf/attachment.html>


More information about the llvm-bugs mailing list