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