// RUN: %check_clang_tidy %s readability-braces-around-statements %t void do_something(const char *) {} bool cond(const char *) { return false; } #define EMPTY_MACRO #define EMPTY_MACRO_FUN() void test() { if (cond("if0") /*comment*/) do_something("same-line"); // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: statement should be inside braces // CHECK-FIXES: if (cond("if0") /*comment*/) { do_something("same-line"); // CHECK-FIXES: } if (cond("if0.1")) do_something("single-line"); // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: statement should be inside braces // CHECK-FIXES: if (cond("if0.1")) { // CHECK-FIXES: } if (cond("if1") /*comment*/) // some comment do_something("if1"); // CHECK-MESSAGES: :[[@LINE-3]]:31: warning: statement should be inside braces // CHECK-FIXES: if (cond("if1") /*comment*/) { // CHECK-FIXES: } if (cond("if2")) { do_something("if2"); } if (cond("if3")) ; // CHECK-MESSAGES: :[[@LINE-2]]:19: warning: statement should be inside braces // CHECK-FIXES: if (cond("if3")) { // CHECK-FIXES: } if (cond("if-else1")) do_something("if-else1"); // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: statement should be inside braces // CHECK-FIXES: if (cond("if-else1")) { // CHECK-FIXES: } else { else do_something("if-else1 else"); // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: statement should be inside braces // CHECK-FIXES: } if (cond("if-else2")) { do_something("if-else2"); } else { do_something("if-else2 else"); } if (cond("if-else if-else1")) do_something("if"); // CHECK-MESSAGES: :[[@LINE-2]]:32: warning: statement should be inside braces // CHECK-FIXES: } else if (cond("else if1")) { else if (cond("else if1")) do_something("else if"); // CHECK-MESSAGES: :[[@LINE-2]]:29: warning: statement should be inside braces else do_something("else"); // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: statement should be inside braces // CHECK-FIXES: } if (cond("if-else if-else2")) { do_something("if"); } else if (cond("else if2")) { do_something("else if"); } else { do_something("else"); } for (;;) do_something("for"); // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: statement should be inside braces // CHECK-FIXES: for (;;) { // CHECK-FIXES-NEXT: do_something("for"); // CHECK-FIXES-NEXT: } for (;;) { do_something("for-ok"); } for (;;) ; // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: statement should be inside braces // CHECK-FIXES: for (;;) { // CHECK-FIXES-NEXT: ; // CHECK-FIXES-NEXT: } int arr[4] = {1, 2, 3, 4}; for (int a : arr) do_something("for-range"); // CHECK-MESSAGES: :[[@LINE-2]]:20: warning: statement should be inside braces // CHECK-FIXES: for (int a : arr) { // CHECK-FIXES-NEXT: do_something("for-range"); // CHECK-FIXES-NEXT: } for (int &assign : arr) assign = 7; // CHECK-MESSAGES: :[[@LINE-2]]:26: warning: statement should be inside braces // CHECK-FIXES: for (int &assign : arr) { // CHECK-FIXES-NEXT: assign = 7; // CHECK-FIXES-NEXT: } for (int ok : arr) { do_something("for-range"); } for (int NullStmt : arr) ; // CHECK-MESSAGES: :[[@LINE-2]]:27: warning: statement should be inside braces // CHECK-FIXES: for (int NullStmt : arr) { // CHECK-FIXES-NEXT: ; // CHECK-FIXES-NEXT: } while (cond("while1")) do_something("while"); // CHECK-MESSAGES: :[[@LINE-2]]:25: warning: statement should be inside braces // CHECK-FIXES: while (cond("while1")) { // CHECK-FIXES: } while (cond("while2")) { do_something("while"); } while (false) ; // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: statement should be inside braces // CHECK-FIXES: while (false) { // CHECK-FIXES: } do do_something("do1"); while (cond("do1")); // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: statement should be inside braces // CHECK-FIXES: do { // CHECK-FIXES: } while (cond("do1")); do { do_something("do2"); } while (cond("do2")); do ; while (false); // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: statement should be inside braces // CHECK-FIXES: do { // CHECK-FIXES: } while (false); if (cond("ifif1")) // comment if (cond("ifif2")) // comment /*comment*/ ; // comment // CHECK-MESSAGES: :[[@LINE-5]]:21: warning: statement should be inside braces // CHECK-MESSAGES: :[[@LINE-4]]:23: warning: statement should be inside braces // CHECK-FIXES: if (cond("ifif1")) { // CHECK-FIXES: if (cond("ifif2")) { // CHECK-FIXES: } // CHECK-FIXES-NEXT: } if (cond("ifif3")) // comment1 if (cond("ifif4")) { // comment2 /*comment3*/; // comment4 } // CHECK-MESSAGES: :[[@LINE-6]]:21: warning: statement should be inside braces // CHECK-FIXES: if (cond("ifif3")) { // CHECK-FIXES-NEXT: // comment1 // CHECK-FIXES-NEXT: if (cond("ifif4")) { // CHECK-FIXES-NEXT: // comment2 // CHECK-FIXES-NEXT: /*comment3*/; // comment4 // CHECK-FIXES-NEXT: } // CHECK-FIXES-NEXT: } if (cond("ifif5")) ; /* multi-line comment */ // CHECK-MESSAGES: :[[@LINE-3]]:21: warning: statement should be inside braces // CHECK-FIXES: if (cond("ifif5")) { // CHECK-FIXES: }/* multi-line if (1) while (2) if (3) for (;;) do ; while(false) /**/;/**/ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: statement should be inside braces // CHECK-MESSAGES: :[[@LINE-2]]:19: warning: statement should be inside braces // CHECK-MESSAGES: :[[@LINE-3]]:26: warning: statement should be inside braces // CHECK-MESSAGES: :[[@LINE-4]]:35: warning: statement should be inside braces // CHECK-MESSAGES: :[[@LINE-5]]:38: warning: statement should be inside braces // CHECK-FIXES: if (1) { while (2) { if (3) { for (;;) { do { ; } while(false) /**/;/**/ // CHECK-FIXES-NEXT: } // CHECK-FIXES-NEXT: } // CHECK-FIXES-NEXT: } // CHECK-FIXES-NEXT: } int S; if (cond("assign with brackets")) S = {5}; // CHECK-MESSAGES: :[[@LINE-2]]:36: warning: statement should be inside braces // CHECK-FIXES: if (cond("assign with brackets")) { // CHECK-FIXES-NEXT: S = {5}; // CHECK-FIXES-NEXT: } if (cond("assign with brackets 2")) S = { 5 } /* comment1 */ ; /* comment2 */ // CHECK-MESSAGES: :[[@LINE-2]]:38: warning: statement should be inside braces // CHECK-FIXES: if (cond("assign with brackets 2")) { // CHECK-FIXES-NEXT: S = { 5 } /* comment1 */ ; /* comment2 */ // CHECK-FIXES-NEXT: } if (cond("return")) return; // CHECK-MESSAGES: :[[@LINE-2]]:22: warning: statement should be inside braces // CHECK-FIXES: if (cond("return")) { // CHECK-FIXES-NEXT: return; // CHECK-FIXES-NEXT: } while (cond("break and continue")) { // CHECK-FIXES: while (cond("break and continue")) { if (true) break; // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: statement should be inside braces // CHECK-FIXES: {{^}} if (true) {{{$}} // CHECK-FIXES-NEXT: {{^}} break;{{$}} // CHECK-FIXES-NEXT: {{^ *}}}{{$}} if (false) continue; // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: statement should be inside braces // CHECK-FIXES: {{^}} if (false) {{{$}} // CHECK-FIXES-NEXT: {{^}} continue;{{$}} // CHECK-FIXES-NEXT: {{^ *}}}{{$}} } //end // CHECK-FIXES: } //end if (cond("decl 1")) int s; else int t; // CHECK-MESSAGES: :[[@LINE-4]]:22: warning: statement should be inside braces // CHECK-MESSAGES: :[[@LINE-3]]:7: warning: statement should be inside braces // CHECK-FIXES: if (cond("decl 1")) { // CHECK-FIXES-NEXT: int s; // CHECK-FIXES-NEXT: } else { // CHECK-FIXES-NEXT: int t; // CHECK-FIXES-NEXT: } if (cond("decl 2")) int s = (5); else int t = (5); // CHECK-MESSAGES: :[[@LINE-4]]:22: warning: statement should be inside braces // CHECK-MESSAGES: :[[@LINE-3]]:7: warning: statement should be inside braces // CHECK-FIXES: if (cond("decl 2")) { // CHECK-FIXES-NEXT: int s = (5); // CHECK-FIXES-NEXT: } else { // CHECK-FIXES-NEXT: int t = (5); // CHECK-FIXES-NEXT: } if (cond("decl 3")) int s = {6}; else int t = {6}; // CHECK-MESSAGES: :[[@LINE-4]]:22: warning: statement should be inside braces // CHECK-MESSAGES: :[[@LINE-3]]:7: warning: statement should be inside braces // CHECK-FIXES: if (cond("decl 3")) { // CHECK-FIXES-NEXT: int s = {6}; // CHECK-FIXES-NEXT: } else { // CHECK-FIXES-NEXT: int t = {6}; // CHECK-FIXES-NEXT: } } void test_whitespace() { while(cond("preserve empty lines")) if(cond("using continue within if")) continue; test(); // CHECK-MESSAGES: :[[@LINE-7]]:{{[0-9]+}}: warning: statement should be inside braces // CHECK-MESSAGES: :[[@LINE-7]]:{{[0-9]+}}: warning: statement should be inside braces // CHECK-FIXES: {{^}} while(cond("preserve empty lines")) {{{$}} // CHECK-FIXES-NEXT: {{^}} if(cond("using continue within if")) {{{$}} // CHECK-FIXES-NEXT: {{^ continue;$}} // The closing brace is added at beginning of line, clang-format can be // applied afterwards. // CHECK-FIXES-NEXT: {{^}$}} // CHECK-FIXES-NEXT: {{^}$}} // Following whitespace is assumed to not to belong to the else branch. // However the check is not possible with CHECK-FIXES-NEXT. // CHECK-FIXES: {{^}} test();{{$}} if (cond("preserve empty lines")) int s; else int t; test(); // CHECK-MESSAGES: :[[@LINE-14]]:{{[0-9]+}}: warning: statement should be inside braces // CHECK-MESSAGES: :[[@LINE-9]]:{{[0-9]+}}: warning: statement should be inside braces // CHECK-FIXES: {{^}} if (cond("preserve empty lines")) {{{$}} // CHECK-FIXES-NEXT: {{^ $}} // CHECK-FIXES-NEXT: {{^ $}} // CHECK-FIXES-NEXT: {{^ int s;$}} // CHECK-FIXES-NEXT: {{^ $}} // CHECK-FIXES-NEXT: {{^ $}} // CHECK-FIXES-NEXT: {{^ } else {$}} // CHECK-FIXES-NEXT: {{^ $}} // CHECK-FIXES-NEXT: {{^ $}} // CHECK-FIXES-NEXT: {{^ int t;$}} // The closing brace is added at beginning of line, clang-format can be // applied afterwards. // CHECK-FIXES-NEXT: {{^}$}} // Following whitespace is assumed to not to belong to the else branch. // CHECK-FIXES-NEXT: {{^ $}} // CHECK-FIXES-NEXT: {{^ $}} // CHECK-FIXES-NEXT: {{^}} test();{{$}} } int test_return_int() { if (cond("return5")) return 5; // CHECK-MESSAGES: :[[@LINE-2]]:23: warning: statement should be inside braces // CHECK-FIXES: if (cond("return5")) { // CHECK-FIXES-NEXT: return 5; // CHECK-FIXES-NEXT: } if (cond("return{6}")) return {6}; // CHECK-MESSAGES: :[[@LINE-2]]:25: warning: statement should be inside braces // CHECK-FIXES: if (cond("return{6}")) { // CHECK-FIXES-NEXT: return {6}; // CHECK-FIXES-NEXT: } // From https://bugs.llvm.org/show_bug.cgi?id=25970 if (cond("25970")) return {25970}; return {!25970}; // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: statement should be inside braces // CHECK-FIXES: if (cond("25970")) { return {25970}; // CHECK-FIXES-NEXT: } // CHECK-FIXES-NEXT: return {!25970}; } void f(const char *p) { if (!p) f("\ "); } // end of f // CHECK-MESSAGES: :[[@LINE-4]]:10: warning: statement should be inside braces // CHECK-FIXES: {{^}} if (!p) {{{$}} // CHECK-FIXES-NEXT: {{^}} f("\{{$}} // CHECK-FIXES-NEXT: {{^}}");{{$}} // CHECK-FIXES-NEXT: {{^}}}{{$}} // CHECK-FIXES-NEXT: {{^}}} // end of f{{$}} #define M(x) x int test_macros(bool b) { if (b) { return 1; } else M(return 2); // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: statement should be inside braces // CHECK-FIXES: } else { // CHECK-FIXES-NEXT: M(return 2); // CHECK-FIXES-NEXT: } M( for (;;) ; ); // CHECK-MESSAGES: :[[@LINE-3]]:13: warning: statement should be inside braces // CHECK-FIXES: {{^}} for (;;) {{{$}} // CHECK-FIXES-NEXT: {{^ ;$}} // CHECK-FIXES-NEXT: {{^}$}} #define WRAP(X) { X; } // This is to ensure no other CHECK-FIXES matches the macro definition: // CHECK-FIXES: WRAP // Use-case: LLVM_DEBUG({ for(...) do_something(); }); WRAP({ for (;;) do_something("for in wrapping macro 1"); }); // CHECK-MESSAGES: :[[@LINE-3]]:13: warning: statement should be inside braces // CHECK-FIXES: for (;;) { // CHECK-FIXES-NEXT: do_something("for in wrapping macro 1"); // CHECK-FIXES-NEXT: } // Use-case: LLVM_DEBUG( for(...) do_something(); ); WRAP( for (;;) do_something("for in wrapping macro 2"); ); // CHECK-MESSAGES: :[[@LINE-3]]:13: warning: statement should be inside braces // CHECK-FIXES: for (;;) { // CHECK-FIXES-NEXT: do_something("for in wrapping macro 2"); // CHECK-FIXES-NEXT: } // Use-case: LLVM_DEBUG( for(...) do_something() ); // This is not supported and this test ensure it's correctly not changed. // We don't want to add the `}` into the Macro and there is no other way // to add it except for introduction of a NullStmt. WRAP( for (;;) do_something("for in wrapping macro 3") ); // CHECK-MESSAGES: :[[@LINE-3]]:13: warning: statement should be inside braces // CHECK-FIXES: WRAP( // CHECK-FIXES-NEXT: for (;;) // CHECK-FIXES-NEXT: do_something("for in wrapping macro 3") // CHECK-FIXES-NEXT: ); // Taken from https://bugs.llvm.org/show_bug.cgi?id=22785 int i; #define MACRO_1 i++ #define MACRO_2 if( i % 3) i--; else if( i % 2) MACRO_1; else MACRO_2; // CHECK-MESSAGES: :[[@LINE-3]]:13: warning: statement should be inside braces // CHECK-MESSAGES: :[[@LINE-3]]:18: warning: statement should be inside braces // CHECK-MESSAGES: :[[@LINE-3]]:7: warning: statement should be inside braces // CHECK-FIXES: if( i % 3) { i--; // CHECK-FIXES-NEXT: } else if( i % 2) { MACRO_1; // CHECK-FIXES-NEXT: } else { MACRO_2; // CHECK-FIXES-NEXT: } // Taken from https://bugs.llvm.org/show_bug.cgi?id=22785 #define M(x) x if (b) return 1; else return 2; // CHECK-MESSAGES: :[[@LINE-4]]:9: warning: statement should be inside braces // CHECK-MESSAGES: :[[@LINE-3]]:7: warning: statement should be inside braces // CHECK-FIXES: if (b) { // CHECK-FIXES-NEXT: return 1; // CHECK-FIXES-NEXT: } else { // CHECK-FIXES-NEXT: return 2; // CHECK-FIXES-NEXT: } if (b) return 1; else M(return 2); // CHECK-MESSAGES: :[[@LINE-4]]:9: warning: statement should be inside braces // CHECK-MESSAGES: :[[@LINE-3]]:7: warning: statement should be inside braces // CHECK-FIXES: if (b) { // CHECK-FIXES-NEXT: return 1; // CHECK-FIXES-NEXT: } else { // CHECK-FIXES-NEXT: M(return 2); // CHECK-FIXES-NEXT: } } template auto constexpr_lambda_1 = [] { if constexpr (A) { 1; } }; template auto constexpr_lambda_2 = [] { // CHECK-MESSAGES: :[[@LINE+1]]:19: warning: statement should be inside braces if constexpr (A) 1; // CHECK-FIXES:if constexpr (A) { // CHECK-FIXES-NEXT:1; // CHECK-FIXES-NEXT:} }; void test_constexpr() { constexpr_lambda_1(); constexpr_lambda_2(); }