<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - NewDeleteLeaks reports false positive with shared_ptr"
href="https://bugs.llvm.org/show_bug.cgi?id=45514">45514</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>NewDeleteLeaks reports false positive with shared_ptr
</td>
</tr>
<tr>
<th>Product</th>
<td>clang
</td>
</tr>
<tr>
<th>Version</th>
<td>unspecified
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>All
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>enhancement
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>Static Analyzer
</td>
</tr>
<tr>
<th>Assignee</th>
<td>dcoughlin@apple.com
</td>
</tr>
<tr>
<th>Reporter</th>
<td>pavel.kryukov@phystech.edu
</td>
</tr>
<tr>
<th>CC</th>
<td>dcoughlin@apple.com, llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>Created <span class=""><a href="attachment.cgi?id=23345" name="attach_23345" title="NewDeleteLeaks false positive">attachment 23345</a> <a href="attachment.cgi?id=23345&action=edit" title="NewDeleteLeaks false positive">[details]</a></span>
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
<span class="quote">> $ clang++-10 --analyze -Xanalyzer -analyzer-output=text -std=c++17 -O3 example.cpp</span >
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.</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>