Open
Description
Hi Static Analyzer Developers,
I was investigating a downstream bug arose from C++ standard library changes.
There is a minimal reproducer:
// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus -verify %s
namespace std {
struct default_delete {
};
template <class _Tp, class _Dp = default_delete >
class unique_ptr {
[[__no_unique_address__]] _Tp * __ptr_;
[[__no_unique_address__]] _Dp __deleter_;
public:
explicit unique_ptr(_Tp* __p) noexcept
: __ptr_(__p),
__deleter_() {}
~unique_ptr() {
delete __ptr_;
}
};
}
struct X {};
int main()
{
std::unique_ptr<X> a(new X()); // leak reported
return 0;
}
From what I observed, the two fields __ptr_
and __deleter_
have overlapping MemRegion
s (Same base and both have 0 offset) because of [[no_unique_address]]
. Then, at the unique_ptr
constructor call, CSA simulates the following two steps:
- assigning
__p
to__ptr_
; and then - assigning
0
to__deleter_
.
Since the two fields have overlapping MemRegion
s, the second assignment removes the binding of __ptr_
. So later the destructor is not able to delete
the allocated object properly. Resulting a false leak report.
If one removes [[no_unique_address]]
from __deleter_
's declaration, the false report goes away.