1 // RUN: %check_clang_tidy %s misc-uniqueptr-reset-release %t
2 
3 // CHECK-FIXES: #include <utility>
4 
5 namespace std {
6 
7 template <typename T>
8 struct default_delete {};
9 
10 template <typename T, class Deleter = std::default_delete<T>>
11 struct unique_ptr {
12   unique_ptr();
13   explicit unique_ptr(T *);
14   template <typename U, typename E>
15   unique_ptr(unique_ptr<U, E> &&);
16   void reset(T *);
17   T *release();
18 };
19 } // namespace std
20 
21 struct Foo {};
22 struct Bar : Foo {};
23 
24 std::unique_ptr<Foo> Create();
25 std::unique_ptr<Foo> &Look();
26 std::unique_ptr<Foo> *Get();
27 
28 using FooFunc = void (*)(Foo *);
29 using BarFunc = void (*)(Bar *);
30 
f()31 void f() {
32   std::unique_ptr<Foo> a, b;
33   std::unique_ptr<Bar> c;
34   std::unique_ptr<Foo> *x = &a;
35   std::unique_ptr<Foo> *y = &b;
36 
37   a.reset(b.release());
38   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'unique_ptr<>' assignment over 'release' and 'reset' [misc-uniqueptr-reset-release]
39   // CHECK-FIXES: a = std::move(b);
40   a.reset(c.release());
41   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'unique_ptr<>' assignment
42   // CHECK-FIXES: a = std::move(c);
43   a.reset(Create().release());
44   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'unique_ptr<>' assignment
45   // CHECK-FIXES: a = Create();
46   x->reset(y->release());
47   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: prefer 'unique_ptr<>' assignment
48   // CHECK-FIXES: *x = std::move(*y);
49   Look().reset(Look().release());
50   // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'unique_ptr<>' assignment
51   // CHECK-FIXES: Look() = std::move(Look());
52   Get()->reset(Get()->release());
53   // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'unique_ptr<>' assignment
54   // CHECK-FIXES: *Get() = std::move(*Get());
55 
56   std::unique_ptr<Bar, FooFunc> func_a, func_b;
57   func_a.reset(func_b.release());
58   // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'unique_ptr<>' assignment
59   // CHECK-FIXES: func_a = std::move(func_b);
60 }
61 
negatives()62 void negatives() {
63   std::unique_ptr<Foo> src;
64   struct OtherDeleter {};
65   std::unique_ptr<Foo, OtherDeleter> dest;
66   dest.reset(src.release());
67 
68   std::unique_ptr<Bar, FooFunc> func_a;
69   std::unique_ptr<Bar, BarFunc> func_b;
70   func_a.reset(func_b.release());
71 }
72