1 // RUN: %check_clang_tidy %s readability-braces-around-statements %t
2 
do_something(const char *)3 void do_something(const char *) {}
4 
cond(const char *)5 bool cond(const char *) {
6   return false;
7 }
8 
9 #define EMPTY_MACRO
10 #define EMPTY_MACRO_FUN()
11 
test()12 void test() {
13   if (cond("if0") /*comment*/) do_something("same-line");
14   // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: statement should be inside braces
15   // CHECK-FIXES:   if (cond("if0") /*comment*/) { do_something("same-line");
16   // CHECK-FIXES: }
17 
18   if (cond("if0.1"))
19     do_something("single-line");
20   // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: statement should be inside braces
21   // CHECK-FIXES: if (cond("if0.1")) {
22   // CHECK-FIXES: }
23 
24   if (cond("if1") /*comment*/)
25     // some comment
26     do_something("if1");
27   // CHECK-MESSAGES: :[[@LINE-3]]:31: warning: statement should be inside braces
28   // CHECK-FIXES: if (cond("if1") /*comment*/) {
29   // CHECK-FIXES: }
30   if (cond("if2")) {
31     do_something("if2");
32   }
33   if (cond("if3"))
34     ;
35   // CHECK-MESSAGES: :[[@LINE-2]]:19: warning: statement should be inside braces
36   // CHECK-FIXES: if (cond("if3")) {
37   // CHECK-FIXES: }
38 
39   if (cond("if-else1"))
40     do_something("if-else1");
41   // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: statement should be inside braces
42   // CHECK-FIXES: if (cond("if-else1")) {
43   // CHECK-FIXES: } else {
44   else
45     do_something("if-else1 else");
46   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: statement should be inside braces
47   // CHECK-FIXES: }
48   if (cond("if-else2")) {
49     do_something("if-else2");
50   } else {
51     do_something("if-else2 else");
52   }
53 
54   if (cond("if-else if-else1"))
55     do_something("if");
56   // CHECK-MESSAGES: :[[@LINE-2]]:32: warning: statement should be inside braces
57   // CHECK-FIXES: } else if (cond("else if1")) {
58   else if (cond("else if1"))
59     do_something("else if");
60   // CHECK-MESSAGES: :[[@LINE-2]]:29: warning: statement should be inside braces
61   else
62     do_something("else");
63   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: statement should be inside braces
64   // CHECK-FIXES: }
65   if (cond("if-else if-else2")) {
66     do_something("if");
67   } else if (cond("else if2")) {
68     do_something("else if");
69   } else {
70     do_something("else");
71   }
72 
73   for (;;)
74     do_something("for");
75   // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: statement should be inside braces
76   // CHECK-FIXES: for (;;) {
77   // CHECK-FIXES-NEXT: do_something("for");
78   // CHECK-FIXES-NEXT: }
79 
80   for (;;) {
81     do_something("for-ok");
82   }
83   for (;;)
84     ;
85   // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: statement should be inside braces
86   // CHECK-FIXES: for (;;) {
87   // CHECK-FIXES-NEXT: ;
88   // CHECK-FIXES-NEXT: }
89 
90   int arr[4] = {1, 2, 3, 4};
91   for (int a : arr)
92     do_something("for-range");
93   // CHECK-MESSAGES: :[[@LINE-2]]:20: warning: statement should be inside braces
94   // CHECK-FIXES: for (int a : arr) {
95   // CHECK-FIXES-NEXT: do_something("for-range");
96   // CHECK-FIXES-NEXT: }
97   for (int &assign : arr)
98     assign = 7;
99   // CHECK-MESSAGES: :[[@LINE-2]]:26: warning: statement should be inside braces
100   // CHECK-FIXES: for (int &assign : arr) {
101   // CHECK-FIXES-NEXT: assign = 7;
102   // CHECK-FIXES-NEXT: }
103   for (int ok : arr) {
104     do_something("for-range");
105   }
106   for (int NullStmt : arr)
107     ;
108   // CHECK-MESSAGES: :[[@LINE-2]]:27: warning: statement should be inside braces
109   // CHECK-FIXES: for (int NullStmt : arr) {
110   // CHECK-FIXES-NEXT: ;
111   // CHECK-FIXES-NEXT: }
112 
113   while (cond("while1"))
114     do_something("while");
115   // CHECK-MESSAGES: :[[@LINE-2]]:25: warning: statement should be inside braces
116   // CHECK-FIXES: while (cond("while1")) {
117   // CHECK-FIXES: }
118   while (cond("while2")) {
119     do_something("while");
120   }
121   while (false)
122     ;
123   // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: statement should be inside braces
124   // CHECK-FIXES: while (false) {
125   // CHECK-FIXES: }
126 
127   do
128     do_something("do1");
129   while (cond("do1"));
130   // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: statement should be inside braces
131   // CHECK-FIXES: do {
132   // CHECK-FIXES: } while (cond("do1"));
133   do {
134     do_something("do2");
135   } while (cond("do2"));
136 
137   do
138     ;
139   while (false);
140   // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: statement should be inside braces
141   // CHECK-FIXES: do {
142   // CHECK-FIXES: } while (false);
143 
144   if (cond("ifif1"))
145     // comment
146     if (cond("ifif2"))
147       // comment
148       /*comment*/ ; // comment
149   // CHECK-MESSAGES: :[[@LINE-5]]:21: warning: statement should be inside braces
150   // CHECK-MESSAGES: :[[@LINE-4]]:23: warning: statement should be inside braces
151   // CHECK-FIXES: if (cond("ifif1")) {
152   // CHECK-FIXES: if (cond("ifif2")) {
153   // CHECK-FIXES: }
154   // CHECK-FIXES-NEXT: }
155 
156   if (cond("ifif3"))
157     // comment1
158     if (cond("ifif4")) {
159       // comment2
160       /*comment3*/; // comment4
161     }
162   // CHECK-MESSAGES: :[[@LINE-6]]:21: warning: statement should be inside braces
163   // CHECK-FIXES: if (cond("ifif3")) {
164   // CHECK-FIXES-NEXT: // comment1
165   // CHECK-FIXES-NEXT: if (cond("ifif4")) {
166   // CHECK-FIXES-NEXT: // comment2
167   // CHECK-FIXES-NEXT: /*comment3*/; // comment4
168   // CHECK-FIXES-NEXT: }
169   // CHECK-FIXES-NEXT: }
170 
171   if (cond("ifif5"))
172     ; /* multi-line
173         comment */
174   // CHECK-MESSAGES: :[[@LINE-3]]:21: warning: statement should be inside braces
175   // CHECK-FIXES: if (cond("ifif5")) {
176   // CHECK-FIXES: }/* multi-line
177 
178   if (1) while (2) if (3) for (;;) do ; while(false) /**/;/**/
179   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: statement should be inside braces
180   // CHECK-MESSAGES: :[[@LINE-2]]:19: warning: statement should be inside braces
181   // CHECK-MESSAGES: :[[@LINE-3]]:26: warning: statement should be inside braces
182   // CHECK-MESSAGES: :[[@LINE-4]]:35: warning: statement should be inside braces
183   // CHECK-MESSAGES: :[[@LINE-5]]:38: warning: statement should be inside braces
184   // CHECK-FIXES: if (1) { while (2) { if (3) { for (;;) { do { ; } while(false) /**/;/**/
185   // CHECK-FIXES-NEXT: }
186   // CHECK-FIXES-NEXT: }
187   // CHECK-FIXES-NEXT: }
188   // CHECK-FIXES-NEXT: }
189 
190   int S;
191   if (cond("assign with brackets"))
192     S = {5};
193   // CHECK-MESSAGES: :[[@LINE-2]]:36: warning: statement should be inside braces
194   // CHECK-FIXES: if (cond("assign with brackets")) {
195   // CHECK-FIXES-NEXT: S = {5};
196   // CHECK-FIXES-NEXT: }
197 
198   if (cond("assign with brackets 2"))
199     S = {  5  } /* comment1 */ ; /* comment2 */
200   // CHECK-MESSAGES: :[[@LINE-2]]:38: warning: statement should be inside braces
201   // CHECK-FIXES: if (cond("assign with brackets 2")) {
202   // CHECK-FIXES-NEXT: S = {  5  } /* comment1 */ ; /* comment2 */
203   // CHECK-FIXES-NEXT: }
204 
205   if (cond("return"))
206     return;
207   // CHECK-MESSAGES: :[[@LINE-2]]:22: warning: statement should be inside braces
208   // CHECK-FIXES: if (cond("return")) {
209   // CHECK-FIXES-NEXT: return;
210   // CHECK-FIXES-NEXT: }
211 
212   while (cond("break and continue")) {
213     // CHECK-FIXES: while (cond("break and continue")) {
214     if (true)
215       break;
216     // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: statement should be inside braces
217     // CHECK-FIXES: {{^}}    if (true) {{{$}}
218     // CHECK-FIXES-NEXT: {{^}}      break;{{$}}
219     // CHECK-FIXES-NEXT: {{^ *}}}{{$}}
220     if (false)
221       continue;
222     // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: statement should be inside braces
223     // CHECK-FIXES: {{^}}    if (false) {{{$}}
224     // CHECK-FIXES-NEXT: {{^}}      continue;{{$}}
225     // CHECK-FIXES-NEXT: {{^ *}}}{{$}}
226   } //end
227   // CHECK-FIXES: } //end
228 
229   if (cond("decl 1"))
230     int s;
231   else
232     int t;
233   // CHECK-MESSAGES: :[[@LINE-4]]:22: warning: statement should be inside braces
234   // CHECK-MESSAGES: :[[@LINE-3]]:7: warning: statement should be inside braces
235   // CHECK-FIXES: if (cond("decl 1")) {
236   // CHECK-FIXES-NEXT: int s;
237   // CHECK-FIXES-NEXT: } else {
238   // CHECK-FIXES-NEXT: int t;
239   // CHECK-FIXES-NEXT: }
240 
241   if (cond("decl 2"))
242     int s = (5);
243   else
244     int t = (5);
245   // CHECK-MESSAGES: :[[@LINE-4]]:22: warning: statement should be inside braces
246   // CHECK-MESSAGES: :[[@LINE-3]]:7: warning: statement should be inside braces
247   // CHECK-FIXES: if (cond("decl 2")) {
248   // CHECK-FIXES-NEXT: int s = (5);
249   // CHECK-FIXES-NEXT: } else {
250   // CHECK-FIXES-NEXT: int t = (5);
251   // CHECK-FIXES-NEXT: }
252 
253   if (cond("decl 3"))
254     int s = {6};
255   else
256     int t = {6};
257   // CHECK-MESSAGES: :[[@LINE-4]]:22: warning: statement should be inside braces
258   // CHECK-MESSAGES: :[[@LINE-3]]:7: warning: statement should be inside braces
259   // CHECK-FIXES: if (cond("decl 3")) {
260   // CHECK-FIXES-NEXT: int s = {6};
261   // CHECK-FIXES-NEXT: } else {
262   // CHECK-FIXES-NEXT: int t = {6};
263   // CHECK-FIXES-NEXT: }
264 }
265 
test_whitespace()266 void test_whitespace() {
267   while(cond("preserve empty lines"))
268     if(cond("using continue within if"))
269       continue;
270 
271 
272   test();
273 
274   // CHECK-MESSAGES: :[[@LINE-7]]:{{[0-9]+}}: warning: statement should be inside braces
275   // CHECK-MESSAGES: :[[@LINE-7]]:{{[0-9]+}}: warning: statement should be inside braces
276   // CHECK-FIXES: {{^}}  while(cond("preserve empty lines")) {{{$}}
277   // CHECK-FIXES-NEXT: {{^}}    if(cond("using continue within if")) {{{$}}
278   // CHECK-FIXES-NEXT: {{^      continue;$}}
279   // The closing brace is added at beginning of line, clang-format can be
280   // applied afterwards.
281   // CHECK-FIXES-NEXT: {{^}$}}
282   // CHECK-FIXES-NEXT: {{^}$}}
283   // Following whitespace is assumed to not to belong to the else branch.
284   // However the check is not possible with CHECK-FIXES-NEXT.
285   // CHECK-FIXES: {{^}}  test();{{$}}
286 
287   if (cond("preserve empty lines"))
288 
289 
290     int s;
291 
292 
293   else
294 
295 
296     int t;
297 
298 
299   test();
300 
301   // CHECK-MESSAGES: :[[@LINE-14]]:{{[0-9]+}}: warning: statement should be inside braces
302   // CHECK-MESSAGES: :[[@LINE-9]]:{{[0-9]+}}: warning: statement should be inside braces
303   // CHECK-FIXES: {{^}}  if (cond("preserve empty lines")) {{{$}}
304   // CHECK-FIXES-NEXT: {{^ $}}
305   // CHECK-FIXES-NEXT: {{^  $}}
306   // CHECK-FIXES-NEXT: {{^    int s;$}}
307   // CHECK-FIXES-NEXT: {{^   $}}
308   // CHECK-FIXES-NEXT: {{^    $}}
309   // CHECK-FIXES-NEXT: {{^  } else {$}}
310   // CHECK-FIXES-NEXT: {{^ $}}
311   // CHECK-FIXES-NEXT: {{^  $}}
312   // CHECK-FIXES-NEXT: {{^    int t;$}}
313   // The closing brace is added at beginning of line, clang-format can be
314   // applied afterwards.
315   // CHECK-FIXES-NEXT: {{^}$}}
316   // Following whitespace is assumed to not to belong to the else branch.
317   // CHECK-FIXES-NEXT: {{^   $}}
318   // CHECK-FIXES-NEXT: {{^    $}}
319   // CHECK-FIXES-NEXT: {{^}}  test();{{$}}
320 }
321 
test_return_int()322 int test_return_int() {
323   if (cond("return5"))
324     return 5;
325   // CHECK-MESSAGES: :[[@LINE-2]]:23: warning: statement should be inside braces
326   // CHECK-FIXES: if (cond("return5")) {
327   // CHECK-FIXES-NEXT: return 5;
328   // CHECK-FIXES-NEXT: }
329 
330   if (cond("return{6}"))
331     return {6};
332   // CHECK-MESSAGES: :[[@LINE-2]]:25: warning: statement should be inside braces
333   // CHECK-FIXES: if (cond("return{6}")) {
334   // CHECK-FIXES-NEXT: return {6};
335   // CHECK-FIXES-NEXT: }
336 
337   // From https://bugs.llvm.org/show_bug.cgi?id=25970
338   if (cond("25970")) return {25970};
339   return {!25970};
340   // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: statement should be inside braces
341   // CHECK-FIXES: if (cond("25970")) { return {25970};
342   // CHECK-FIXES-NEXT: }
343   // CHECK-FIXES-NEXT: return {!25970};
344 }
345 
f(const char * p)346 void f(const char *p) {
347   if (!p)
348     f("\
349 ");
350 } // end of f
351 // CHECK-MESSAGES: :[[@LINE-4]]:10: warning: statement should be inside braces
352 // CHECK-FIXES:      {{^}}  if (!p) {{{$}}
353 // CHECK-FIXES-NEXT: {{^}}    f("\{{$}}
354 // CHECK-FIXES-NEXT: {{^}}");{{$}}
355 // CHECK-FIXES-NEXT: {{^}}}{{$}}
356 // CHECK-FIXES-NEXT: {{^}}} // end of f{{$}}
357 
358 #define M(x) x
359 
test_macros(bool b)360 int test_macros(bool b) {
361   if (b) {
362     return 1;
363   } else
364     M(return 2);
365   // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: statement should be inside braces
366   // CHECK-FIXES: } else {
367   // CHECK-FIXES-NEXT:   M(return 2);
368   // CHECK-FIXES-NEXT: }
369   M(
370     for (;;)
371       ;
372   );
373   // CHECK-MESSAGES: :[[@LINE-3]]:13: warning: statement should be inside braces
374   // CHECK-FIXES: {{^}}    for (;;) {{{$}}
375   // CHECK-FIXES-NEXT: {{^      ;$}}
376   // CHECK-FIXES-NEXT: {{^}$}}
377 
378 
379   #define WRAP(X) { X; }
380   // This is to ensure no other CHECK-FIXES matches the macro definition:
381   // CHECK-FIXES: WRAP
382 
383   // Use-case: LLVM_DEBUG({ for(...) do_something(); });
384   WRAP({
385     for (;;)
386       do_something("for in wrapping macro 1");
387     });
388   // CHECK-MESSAGES: :[[@LINE-3]]:13: warning: statement should be inside braces
389   // CHECK-FIXES: for (;;) {
390   // CHECK-FIXES-NEXT: do_something("for in wrapping macro 1");
391   // CHECK-FIXES-NEXT: }
392 
393   // Use-case: LLVM_DEBUG( for(...) do_something(); );
394   WRAP(
395     for (;;)
396       do_something("for in wrapping macro 2");
397     );
398   // CHECK-MESSAGES: :[[@LINE-3]]:13: warning: statement should be inside braces
399   // CHECK-FIXES: for (;;) {
400   // CHECK-FIXES-NEXT: do_something("for in wrapping macro 2");
401   // CHECK-FIXES-NEXT: }
402 
403   // Use-case: LLVM_DEBUG( for(...) do_something() );
404   // This is not supported and this test ensure it's correctly not changed.
405   // We don't want to add the `}` into the Macro and there is no other way
406   // to add it except for introduction of a NullStmt.
407   WRAP(
408     for (;;)
409         do_something("for in wrapping macro 3")
410     );
411   // CHECK-MESSAGES: :[[@LINE-3]]:13: warning: statement should be inside braces
412   // CHECK-FIXES: WRAP(
413   // CHECK-FIXES-NEXT: for (;;)
414   // CHECK-FIXES-NEXT: do_something("for in wrapping macro 3")
415   // CHECK-FIXES-NEXT: );
416 
417   // Taken from https://bugs.llvm.org/show_bug.cgi?id=22785
418   int i;
419   #define MACRO_1 i++
420   #define MACRO_2
421   if( i % 3) i--;
422   else if( i % 2) MACRO_1;
423   else MACRO_2;
424   // CHECK-MESSAGES: :[[@LINE-3]]:13: warning: statement should be inside braces
425   // CHECK-MESSAGES: :[[@LINE-3]]:18: warning: statement should be inside braces
426   // CHECK-MESSAGES: :[[@LINE-3]]:7: warning: statement should be inside braces
427   // CHECK-FIXES: if( i % 3) { i--;
428   // CHECK-FIXES-NEXT: } else if( i % 2) { MACRO_1;
429   // CHECK-FIXES-NEXT: } else { MACRO_2;
430   // CHECK-FIXES-NEXT: }
431 
432   // Taken from https://bugs.llvm.org/show_bug.cgi?id=22785
433   #define M(x) x
434 
435   if (b)
436     return 1;
437   else
438     return 2;
439   // CHECK-MESSAGES: :[[@LINE-4]]:9: warning: statement should be inside braces
440   // CHECK-MESSAGES: :[[@LINE-3]]:7: warning: statement should be inside braces
441   // CHECK-FIXES: if (b) {
442   // CHECK-FIXES-NEXT: return 1;
443   // CHECK-FIXES-NEXT: } else {
444   // CHECK-FIXES-NEXT: return 2;
445   // CHECK-FIXES-NEXT: }
446 
447   if (b)
448     return 1;
449   else
450     M(return 2);
451   // CHECK-MESSAGES: :[[@LINE-4]]:9: warning: statement should be inside braces
452   // CHECK-MESSAGES: :[[@LINE-3]]:7: warning: statement should be inside braces
453   // CHECK-FIXES: if (b) {
454   // CHECK-FIXES-NEXT: return 1;
455   // CHECK-FIXES-NEXT: } else {
456   // CHECK-FIXES-NEXT: M(return 2);
457   // CHECK-FIXES-NEXT: }
458 
459 }
460