
The original commit assumes that `CXXConstructExpr->getType()->getAsRecordDecl()` is always a `CXXRecordDecl` but it is not true for ObjC programs. This relanding changes `cast<CXXRecordDecl>(CXXConstructExpr->getType()->getAsRecordDecl())` to `dyn_cast_or_null<CXXRecordDecl>(CXXConstructExpr->getType()->getAsRecordDecl())` This reverts commit 9048c2d4f239cb47fed17cb150e2bbf3934454c2. rdar://146753089
51 lines
1.3 KiB
C++
51 lines
1.3 KiB
C++
// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus -verify %s
|
|
// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus -verify %s -DEMPTY_CLASS
|
|
// UNSUPPORTED: system-windows
|
|
// expected-no-diagnostics
|
|
|
|
// This test reproduces the issue that previously the static analyzer
|
|
// initialized an [[no_unique_address]] empty field to zero,
|
|
// over-writing a non-empty field with the same offset.
|
|
|
|
namespace std {
|
|
#ifdef EMPTY_CLASS
|
|
|
|
struct default_delete {};
|
|
template <class _Tp, class _Dp = default_delete >
|
|
#else
|
|
// Class with methods and static members is still empty:
|
|
template <typename T>
|
|
class default_delete {
|
|
T dump();
|
|
static T x;
|
|
};
|
|
template <class _Tp, class _Dp = default_delete<_Tp> >
|
|
#endif
|
|
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()
|
|
{
|
|
// Previously a leak falsely reported here. It was because the
|
|
// Static Analyzer engine simulated the initialization of
|
|
// `__deleter__` incorrectly. The engine assigned zero to
|
|
// `__deleter__`--an empty record sharing offset with `__ptr__`.
|
|
// The assignment over wrote `__ptr__`.
|
|
std::unique_ptr<X> a(new X());
|
|
return 0;
|
|
}
|