1 // RUN: %check_clang_tidy %s readability-redundant-control-flow %t 2 3 void g(int i); 4 void j(); 5 f()6void 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 g()13void 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 g(int i)21void g(int i) { 22 if (i < 0) { 23 return; 24 } 25 if (i < 10) { 26 f(); 27 } 28 } 29 h()30int h() { 31 return 1; 32 } 33 j()34void j() { 35 } 36 k()37void 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 k2()46void 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 m()56void 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 p()68void 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 im_not_dead(int i)80void im_not_dead(int i) { 81 if (i > 0) { 82 return; 83 } 84 g(); 85 } 86 im_still_not_dead(int i)87void 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 im_dead(int i)96void im_dead(int i) { 97 if (i > 0) { 98 return; 99 g(); 100 } 101 g(); 102 } 103 im_still_dead(int i)104void 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 void_return()114void void_return() { 115 return g(); 116 } 117 nested_return_unmolested()118void nested_return_unmolested() { 119 g(); 120 { 121 g(); 122 return; 123 } 124 } 125 nested_continue_unmolested()126void 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 macro_return()145void macro_return() { 146 MACRO_RETURN_UNMOLESTED(g); 147 } 148 macro_continue()149void 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 macro_arg_return()163void macro_arg_return() { 164 MACRO_RETURN_ARG(return); 165 } 166 macro_arg_continue()167void macro_arg_continue() { 168 MACRO_CONTINUE_ARG(continue); 169 } 170 171 template <typename T> template_return(T check)172void 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 <> template_return(int check)185void 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> template_loop(T end)198void 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 <> template_loop(int end)208void 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 call_templates()217void call_templates() { 218 template_return(10); 219 template_return(10.0f); 220 template_return(10.0); 221 template_loop(10); 222 template_loop(10L); 223 template_loop(10U); 224 } 225