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*89a1d03eSRichardvoid 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*89a1d03eSRichardvoid 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