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