================ @@ -0,0 +1,45 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus -verify %s -DEMPTY_CLASS + +// 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 + + template <typename T> + class default_delete { + T dump(); + static T x; + }; + template <class _Tp, class _Dp = default_delete<_Tp> > +#else + + struct default_delete {}; + template <class _Tp, class _Dp = default_delete > +#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() +{ + std::unique_ptr<X> a(new X()); // previously leak falsely reported ---------------- steakhal wrote:
I think we should mention that how did we have a FP here. Like first `__ptr_` was assigned in the init-list, then the `__deleter_`, which happened to overlap with the previous store and overwrite the pointer causing a false leak diagnostic. If we ever break this test again, that would help us understand the flow of events here. I recall debugging this exact case, and I wasn't happy spending that time. I wish I had some pointers about this. https://github.com/llvm/llvm-project/pull/138594 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits