1 // RUN: %check_clang_tidy %s readability-uniqueptr-delete-release %t
2 
3 namespace std {
4 template <typename T>
5 struct default_delete {};
6 
7 template <typename T, typename D = default_delete<T>>
8 class unique_ptr {
9  public:
10   unique_ptr();
11   ~unique_ptr();
12   explicit unique_ptr(T*);
13   template <typename U, typename E>
14   unique_ptr(unique_ptr<U, E>&&);
15   T* release();
16 };
17 }  // namespace std
18 
19 std::unique_ptr<int>& ReturnsAUnique();
20 
Positives()21 void Positives() {
22   std::unique_ptr<int> P;
23   delete P.release();
24   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer '= nullptr' to 'delete x.release()' to reset unique_ptr<> objects [readability-uniqueptr-delete-release]
25   // CHECK-FIXES: {{^}}  P = nullptr;
26 
27   auto P2 = P;
28   delete P2.release();
29   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer '= nullptr' to 'delete x.release()' to reset unique_ptr<> objects [readability-uniqueptr-delete-release]
30   // CHECK-FIXES: {{^}}  P2 = nullptr;
31 
32   std::unique_ptr<int> Array[20];
33   delete Array[4].release();
34   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer '= nullptr' to 'delete
35   // CHECK-FIXES: {{^}}  Array[4] = nullptr;
36 
37   delete ReturnsAUnique().release();
38   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer '= nullptr' to 'delete
39   // CHECK-FIXES: {{^}}  ReturnsAUnique() = nullptr;
40 }
41 
42 struct NotDefaultDeleter {};
43 
44 struct NotUniquePtr {
45   int* release();
46 };
47 
Negatives()48 void Negatives() {
49   std::unique_ptr<int, NotDefaultDeleter> P;
50   delete P.release();
51 
52   NotUniquePtr P2;
53   delete P2.release();
54 }
55 
56 template <typename T, typename D>
NegativeDeleterT()57 void NegativeDeleterT() {
58   // Ideally this would trigger a warning, but we have all dependent types
59   // disabled for now.
60   std::unique_ptr<T> P;
61   delete P.release();
62 
63   // We ignore this one because the deleter is a template argument.
64   // Not all instantiations will use the default deleter.
65   std::unique_ptr<int, D> P2;
66   delete P2.release();
67 }
68 template void NegativeDeleterT<int, std::default_delete<int>>();
69 
70 // Test some macros
71 
72 #define DELETE_RELEASE(x) delete (x).release()
NegativesWithTemplate()73 void NegativesWithTemplate() {
74   std::unique_ptr<int> P;
75   DELETE_RELEASE(P);
76 }
77