1// RUN: %check_clang_tidy %s readability-uniqueptr-delete-release %t -check-suffix=NULLPTR
2// RUN: %check_clang_tidy %s readability-uniqueptr-delete-release %t -check-suffix=RESET -config='{ \
3// RUN: CheckOptions: {readability-uniqueptr-delete-release.PreferResetCall: true}}'
4namespace std {
5template <typename T>
6struct default_delete {};
7
8template <typename T, typename D = default_delete<T>>
9class unique_ptr {
10 public:
11 unique_ptr();
12 ~unique_ptr();
13 explicit unique_ptr(T*);
14 template <typename U, typename E>
15 unique_ptr(unique_ptr<U, E>&&);
16 T* release();
17 void reset(T *P = nullptr);
18 T &operator*() const;
19 T *operator->() const;
20};
21} // namespace std
22
23std::unique_ptr<int>& ReturnsAUnique();
24
25void Positives() {
26 std::unique_ptr<int> P;
27 delete P.release();
28 // CHECK-MESSAGES-NULLPTR: :[[@LINE-1]]:3: warning: prefer '= nullptr' to reset 'unique_ptr<>' objects
29 // CHECK-MESSAGES-RESET: :[[@LINE-2]]:3: warning: prefer 'reset()' to reset 'unique_ptr<>' objects
30 // CHECK-FIXES-NULLPTR: {{^}} P = nullptr;
31 // CHECK-FIXES-RESET: {{^}} P.reset();
32
33 auto P2 = P;
34 delete P2.release();
35 // CHECK-MESSAGES-NULLPTR: :[[@LINE-1]]:3: warning: prefer '= nullptr' to reset 'unique_ptr<>' objects
36 // CHECK-MESSAGES-RESET: :[[@LINE-2]]:3: warning: prefer 'reset()' to reset 'unique_ptr<>' objects
37 // CHECK-FIXES-NULLPTR: {{^}} P2 = nullptr;
38 // CHECK-FIXES-RESET: {{^}} P2.reset();
39
40 delete (P2.release());
41 // CHECK-MESSAGES-NULLPTR: :[[@LINE-1]]:3: warning: prefer '= nullptr'
42 // CHECK-MESSAGES-RESET: :[[@LINE-2]]:3: warning: prefer 'reset()'
43 // CHECK-FIXES-NULLPTR: {{^}} (P2 = nullptr);
44 // CHECK-FIXES-RESET: {{^}} (P2.reset());
45
46 std::unique_ptr<int> Array[20];
47 delete Array[4].release();
48 // CHECK-MESSAGES-NULLPTR: :[[@LINE-1]]:3: warning: prefer '= nullptr'
49 // CHECK-MESSAGES-RESET: :[[@LINE-2]]:3: warning: prefer 'reset()'
50 // CHECK-FIXES-NULLPTR: {{^}} Array[4] = nullptr;
51 // CHECK-FIXES-RESET: {{^}} Array[4].reset();
52
53 delete ReturnsAUnique().release();
54 // CHECK-MESSAGES-NULLPTR: :[[@LINE-1]]:3: warning: prefer '= nullptr'
55 // CHECK-MESSAGES-RESET: :[[@LINE-2]]:3: warning: prefer 'reset()'
56 // CHECK-FIXES-NULLPTR: {{^}} ReturnsAUnique() = nullptr;
57 // CHECK-FIXES-RESET: {{^}} ReturnsAUnique().reset();
58
59 std::unique_ptr<int> *P3(&P);
60 delete P3->release();
61 // CHECK-MESSAGES-NULLPTR: :[[@LINE-1]]:3: warning: prefer '= nullptr'
62 // CHECK-MESSAGES-RESET: :[[@LINE-2]]:3: warning: prefer 'reset()'
63 // CHECK-FIXES-NULLPTR: {{^}} *P3 = nullptr;
64 // CHECK-FIXES-RESET: {{^}} P3->reset();
65
66 std::unique_ptr<std::unique_ptr<int>> P4;
67 delete (*P4).release();
68 // CHECK-MESSAGES-NULLPTR: :[[@LINE-1]]:3: warning: prefer '= nullptr'
69 // CHECK-MESSAGES-RESET: :[[@LINE-2]]:3: warning: prefer 'reset()'
70 // CHECK-FIXES-NULLPTR: {{^}} (*P4) = nullptr;
71 // CHECK-FIXES-RESET: {{^}} (*P4).reset();
72
73 delete P4->release();
74 // CHECK-MESSAGES-NULLPTR: :[[@LINE-1]]:3: warning: prefer '= nullptr'
75 // CHECK-MESSAGES-RESET: :[[@LINE-2]]:3: warning: prefer 'reset()'
76 // CHECK-FIXES-NULLPTR: {{^}} *P4 = nullptr;
77 // CHECK-FIXES-RESET: {{^}} P4->reset();
78
79 delete (P4)->release();
80 // CHECK-MESSAGES-NULLPTR: :[[@LINE-1]]:3: warning: prefer '= nullptr'
81 // CHECK-MESSAGES-RESET: :[[@LINE-2]]:3: warning: prefer 'reset()'
82 // CHECK-FIXES-NULLPTR: {{^}} *(P4) = nullptr;
83 // CHECK-FIXES-RESET: {{^}} (P4)->reset();
84}
85
86struct NotDefaultDeleter {};
87
88struct NotUniquePtr {
89 int* release();
90};
91
92void Negatives() {
93 std::unique_ptr<int, NotDefaultDeleter> P;
94 delete P.release();
95
96 NotUniquePtr P2;
97 delete P2.release();
98
99 // We don't trigger on bound member function calls.
100 delete (P2.release)();
101}
102
103template <typename T, typename D>
104void NegativeDeleterT() {
105 // Ideally this would trigger a warning, but we have all dependent types
106 // disabled for now.
107 std::unique_ptr<T> P;
108 delete P.release();
109
110 // We ignore this one because the deleter is a template argument.
111 // Not all instantiations will use the default deleter.
112 std::unique_ptr<int, D> P2;
113 delete P2.release();
114}
115template void NegativeDeleterT<int, std::default_delete<int>>();
116
117// Test some macros
118
119#define DELETE_RELEASE(x) delete (x).release()
120void NegativesWithTemplate() {
121 std::unique_ptr<int> P;
122 DELETE_RELEASE(P);
123}
124

source code of clang-tools-extra/test/clang-tidy/checkers/readability/uniqueptr-delete-release.cpp