1 | // RUN: %check_clang_tidy %s readability-redundant-control-flow %t |
2 | |
3 | void g(int i); |
4 | void j(); |
5 | |
6 | void f() { |
7 | return; |
8 | } |
9 | // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: redundant return statement at the end of a function with a void return type [readability-redundant-control-flow] |
10 | // CHECK-FIXES: {{^}}void f() {{{$}} |
11 | // CHECK-FIXES-NEXT: {{^ *}$}} |
12 | |
13 | void g() { |
14 | f(); |
15 | return; |
16 | } |
17 | // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: redundant return statement |
18 | // CHECK-FIXES: {{^ }}f();{{$}} |
19 | // CHECK-FIXES-NEXT: {{^ *}$}} |
20 | |
21 | void g(int i) { |
22 | if (i < 0) { |
23 | return; |
24 | } |
25 | if (i < 10) { |
26 | f(); |
27 | } |
28 | } |
29 | |
30 | int h() { |
31 | return 1; |
32 | } |
33 | |
34 | void j() { |
35 | } |
36 | |
37 | void k() { |
38 | for (int i = 0; i < 10; ++i) { |
39 | continue; |
40 | } |
41 | } |
42 | // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: redundant continue statement at the end of loop statement |
43 | // CHECK-FIXES: {{^}} for (int i = 0; i < 10; ++i) {{{$}} |
44 | // CHECK-FIXES-NEXT: {{^ *}$}} |
45 | |
46 | void k2() { |
47 | int v[10] = { 0 }; |
48 | for (auto i : v) { |
49 | continue; |
50 | } |
51 | } |
52 | // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: redundant continue statement |
53 | // CHECK-FIXES: {{^}} for (auto i : v) {{{$}} |
54 | // CHECK-FIXES-NEXT: {{^ *}$}} |
55 | |
56 | void m() { |
57 | int i = 0; |
58 | do { |
59 | ++i; |
60 | continue; |
61 | } while (i < 10); |
62 | } |
63 | // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: redundant continue statement |
64 | // CHECK-FIXES: {{^ do {$}} |
65 | // CHECK-FIXES-NEXT: {{^}} ++i;{{$}} |
66 | // CHECK-FIXES-NEXT: {{^ *}}} while (i < 10);{{$}} |
67 | |
68 | void p() { |
69 | int i = 0; |
70 | while (i < 10) { |
71 | ++i; |
72 | continue; |
73 | } |
74 | } |
75 | // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: redundant continue statement |
76 | // CHECK-FIXES: {{^}} while (i < 10) {{{$}} |
77 | // CHECK-FIXES-NEXT: {{^}} ++i;{{$}} |
78 | // CHECK-FIXES-NEXT: {{^ *}$}} |
79 | |
80 | void im_not_dead(int i) { |
81 | if (i > 0) { |
82 | return; |
83 | } |
84 | g(); |
85 | } |
86 | |
87 | void im_still_not_dead(int i) { |
88 | for (int j = 0; j < 10; ++j) { |
89 | if (i < 10) { |
90 | continue; |
91 | } |
92 | g(); |
93 | } |
94 | } |
95 | |
96 | void im_dead(int i) { |
97 | if (i > 0) { |
98 | return; |
99 | g(); |
100 | } |
101 | g(); |
102 | } |
103 | |
104 | void im_still_dead(int i) { |
105 | for (int j = 0; j < 10; ++j) { |
106 | if (i < 10) { |
107 | continue; |
108 | g(); |
109 | } |
110 | g(); |
111 | } |
112 | } |
113 | |
114 | void void_return() { |
115 | return g(); |
116 | } |
117 | |
118 | void nested_return_unmolested() { |
119 | g(); |
120 | { |
121 | g(); |
122 | return; |
123 | } |
124 | } |
125 | |
126 | void nested_continue_unmolested() { |
127 | for (int i = 0; i < 10; ++i) { |
128 | if (i < 5) { |
129 | continue; |
130 | } |
131 | } |
132 | } |
133 | |
134 | #define MACRO_RETURN_UNMOLESTED(fn_) \ |
135 | (fn_)(); \ |
136 | return |
137 | |
138 | #define MACRO_CONTINUE_UNMOLESTED(x_) \ |
139 | do { \ |
140 | for (int i = 0; i < (x_); ++i) { \ |
141 | continue; \ |
142 | } \ |
143 | } while (false) |
144 | |
145 | void macro_return() { |
146 | MACRO_RETURN_UNMOLESTED(g); |
147 | } |
148 | |
149 | void macro_continue() { |
150 | MACRO_CONTINUE_UNMOLESTED(10); |
151 | } |
152 | |
153 | #define MACRO_RETURN_ARG(stmt_) \ |
154 | stmt_ |
155 | |
156 | #define MACRO_CONTINUE_ARG(stmt_) \ |
157 | do { \ |
158 | for (int i = 0; i < 10; ++i) { \ |
159 | stmt_; \ |
160 | } \ |
161 | } while (false) |
162 | |
163 | void macro_arg_return() { |
164 | MACRO_RETURN_ARG(return); |
165 | } |
166 | |
167 | void macro_arg_continue() { |
168 | MACRO_CONTINUE_ARG(continue); |
169 | } |
170 | |
171 | template <typename T> |
172 | void template_return(T check) { |
173 | if (check < T(0)) { |
174 | return; |
175 | } |
176 | return; |
177 | } |
178 | // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: redundant return statement |
179 | // CHECK-FIXES: {{^}} if (check < T(0)) {{{$}} |
180 | // CHECK-FIXES-NEXT: {{^ return;$}} |
181 | // CHECK-FIXES-NEXT: {{^ *}$}} |
182 | // CHECK-FIXES-NEXT: {{^ *}$}} |
183 | |
184 | template <> |
185 | void template_return(int check) { |
186 | if (check < 0) { |
187 | return; |
188 | } |
189 | return; |
190 | } |
191 | // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: redundant return statement |
192 | // CHECK-FIXES: {{^}} if (check < 0) {{{$}} |
193 | // CHECK-FIXES-NEXT: {{^ return;$}} |
194 | // CHECK-FIXES-NEXT: {{^ *}$}} |
195 | // CHECK-FIXES-NEXT: {{^ *}$}} |
196 | |
197 | template <typename T> |
198 | void template_loop(T end) { |
199 | for (T i = 0; i < end; ++i) { |
200 | continue; |
201 | } |
202 | } |
203 | // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: redundant continue statement |
204 | // CHECK-FIXES: {{^}} for (T i = 0; i < end; ++i) {{{$}} |
205 | // CHECK-FIXES-NEXT: {{^ *}$}} |
206 | |
207 | template <> |
208 | void template_loop(int end) { |
209 | for (int i = 0; i < end; ++i) { |
210 | continue; |
211 | } |
212 | } |
213 | // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: redundant continue statement |
214 | // CHECK-FIXES: {{^}} for (int i = 0; i < end; ++i) {{{$}} |
215 | // CHECK-FIXES-NEXT: {{^ *}$}} |
216 | |
217 | void call_templates() { |
218 | template_return(check: 10); |
219 | template_return(check: 10.0f); |
220 | template_return(check: 10.0); |
221 | template_loop(end: 10); |
222 | template_loop(end: 10L); |
223 | template_loop(end: 10U); |
224 | } |
225 | |