For smart pointers like std::unique_ptr which uniquely owns the
underlying object, treat the mutation of the pointee as mutation of the
smart pointer itself.
This gives better behavior for cases like this:
void f(std::vector<std::unique_ptr<Foo>> v) { // undesirable analyze result of `v` as not mutated. for (auto& p : v) { p->mutate(); // only const member function `operator->` is invoked on `p` } }
Template testcases i miss: