Issue 137252
Summary [StaticAnalyzer] A Static Analyzer bug related to initializing [[__no_unique_address__]] fields
Labels clang:static analyzer
Assignees
Reporter ziqingluo-90
    Hi Static Analyzer Developers,

I was investigating a downstream bug arose from C++ standard library changes. 
There is a minimal reproducer:
```
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: 
1. assigning `__p` to `__ptr_`; and then 
2. 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.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to