1 #include "../../clang/unittests/ASTMatchers/ASTMatchersTest.h" 2 #include "ClangTidyTest.h" 3 #include "readability/BracesAroundStatementsCheck.h" 4 #include "readability/NamespaceCommentCheck.h" 5 #include "gtest/gtest.h" 6 7 namespace clang { 8 namespace tidy { 9 namespace test { 10 11 using readability::BracesAroundStatementsCheck; 12 using readability::NamespaceCommentCheck; 13 using namespace ast_matchers; 14 15 // Copied from ASTMatchersTests 16 static std::vector<TestClangConfig> allTestClangConfigs() { 17 std::vector<TestClangConfig> all_configs; 18 for (TestLanguage lang : {Lang_C89, Lang_C99, Lang_CXX03, Lang_CXX11, 19 Lang_CXX14, Lang_CXX17, Lang_CXX20}) { 20 TestClangConfig config; 21 config.Language = lang; 22 23 // Use an unknown-unknown triple so we don't instantiate the full system 24 // toolchain. On Linux, instantiating the toolchain involves stat'ing 25 // large portions of /usr/lib, and this slows down not only this test, but 26 // all other tests, via contention in the kernel. 27 // 28 // FIXME: This is a hack to work around the fact that there's no way to do 29 // the equivalent of runToolOnCodeWithArgs without instantiating a full 30 // Driver. We should consider having a function, at least for tests, that 31 // invokes cc1. 32 config.Target = "i386-unknown-unknown"; 33 all_configs.push_back(config); 34 35 // Windows target is interesting to test because it enables 36 // `-fdelayed-template-parsing`. 37 config.Target = "x86_64-pc-win32-msvc"; 38 all_configs.push_back(config); 39 } 40 return all_configs; 41 } 42 43 INSTANTIATE_TEST_SUITE_P(ASTMatchersTests, ASTMatchersTest, 44 testing::ValuesIn(allTestClangConfigs())); 45 46 TEST(NamespaceCommentCheckTest, Basic) { 47 EXPECT_EQ("namespace i {\n} // namespace i", 48 runCheckOnCode<NamespaceCommentCheck>("namespace i {\n}")); 49 EXPECT_EQ("namespace {\n} // namespace", 50 runCheckOnCode<NamespaceCommentCheck>("namespace {\n}")); 51 EXPECT_EQ("namespace i { namespace j {\n} // namespace j\n } // namespace i", 52 runCheckOnCode<NamespaceCommentCheck>( 53 "namespace i { namespace j {\n} }")); 54 } 55 56 TEST(NamespaceCommentCheckTest, SingleLineNamespaces) { 57 EXPECT_EQ( 58 "namespace i { namespace j { } }", 59 runCheckOnCode<NamespaceCommentCheck>("namespace i { namespace j { } }")); 60 } 61 62 TEST(NamespaceCommentCheckTest, CheckExistingComments) { 63 EXPECT_EQ("namespace i { namespace j {\n" 64 "} /* namespace j */ } // namespace i\n" 65 " /* random comment */", 66 runCheckOnCode<NamespaceCommentCheck>( 67 "namespace i { namespace j {\n" 68 "} /* namespace j */ } /* random comment */")); 69 EXPECT_EQ("namespace {\n" 70 "} // namespace", 71 runCheckOnCode<NamespaceCommentCheck>("namespace {\n" 72 "} // namespace")); 73 EXPECT_EQ("namespace {\n" 74 "} //namespace", 75 runCheckOnCode<NamespaceCommentCheck>("namespace {\n" 76 "} //namespace")); 77 EXPECT_EQ("namespace {\n" 78 "} // anonymous namespace", 79 runCheckOnCode<NamespaceCommentCheck>("namespace {\n" 80 "} // anonymous namespace")); 81 EXPECT_EQ("namespace {\n" 82 "} // Anonymous namespace.", 83 runCheckOnCode<NamespaceCommentCheck>("namespace {\n" 84 "} // Anonymous namespace.")); 85 EXPECT_EQ( 86 "namespace q {\n" 87 "} // namespace q", 88 runCheckOnCode<NamespaceCommentCheck>("namespace q {\n" 89 "} // anonymous namespace q")); 90 EXPECT_EQ( 91 "namespace My_NameSpace123 {\n" 92 "} // namespace My_NameSpace123", 93 runCheckOnCode<NamespaceCommentCheck>("namespace My_NameSpace123 {\n" 94 "} // namespace My_NameSpace123")); 95 EXPECT_EQ( 96 "namespace My_NameSpace123 {\n" 97 "} //namespace My_NameSpace123", 98 runCheckOnCode<NamespaceCommentCheck>("namespace My_NameSpace123 {\n" 99 "} //namespace My_NameSpace123")); 100 EXPECT_EQ("namespace My_NameSpace123 {\n" 101 "} // end namespace My_NameSpace123", 102 runCheckOnCode<NamespaceCommentCheck>( 103 "namespace My_NameSpace123 {\n" 104 "} // end namespace My_NameSpace123")); 105 // Understand comments only on the same line. 106 EXPECT_EQ("namespace {\n" 107 "} // namespace\n" 108 "// namespace", 109 runCheckOnCode<NamespaceCommentCheck>("namespace {\n" 110 "}\n" 111 "// namespace")); 112 } 113 114 TEST(NamespaceCommentCheckTest, FixWrongComments) { 115 EXPECT_EQ("namespace i { namespace jJ0_ {\n" 116 "} // namespace jJ0_\n" 117 " } // namespace i\n" 118 " /* random comment */", 119 runCheckOnCode<NamespaceCommentCheck>( 120 "namespace i { namespace jJ0_ {\n" 121 "} /* namespace qqq */ } /* random comment */")); 122 EXPECT_EQ("namespace {\n" 123 "} // namespace", 124 runCheckOnCode<NamespaceCommentCheck>("namespace {\n" 125 "} // namespace asdf")); 126 // Remove unknown line comments. These are likely to be an unrecognized form 127 // of a namespace ending comment. 128 EXPECT_EQ("namespace {\n" 129 "} // namespace", 130 runCheckOnCode<NamespaceCommentCheck>("namespace {\n" 131 "} // random text")); 132 } 133 134 TEST(BracesAroundStatementsCheckTest, IfWithComments) { 135 EXPECT_EQ("int main() {\n" 136 " if (false /*dummy token*/) {\n" 137 " // comment\n" 138 " return -1; /**/\n" 139 "}\n" 140 " if (false) {\n" 141 " return -1; // comment\n" 142 "}\n" 143 " if (false) {\n" 144 " return -1; \n" 145 "}/* multi-line \n comment */\n" 146 "}", 147 runCheckOnCode<BracesAroundStatementsCheck>( 148 "int main() {\n" 149 " if (false /*dummy token*/)\n" 150 " // comment\n" 151 " return -1; /**/\n" 152 " if (false)\n" 153 " return -1; // comment\n" 154 " if (false)\n" 155 " return -1; /* multi-line \n comment */\n" 156 "}")); 157 EXPECT_EQ("int main() {\n" 158 " if (false /*dummy token*/) {\n" 159 " // comment\n" 160 " return -1 /**/ ;\n" 161 "}\n" 162 "}", 163 runCheckOnCode<BracesAroundStatementsCheck>( 164 "int main() {\n" 165 " if (false /*dummy token*/)\n" 166 " // comment\n" 167 " return -1 /**/ ;\n" 168 "}")); 169 } 170 171 TEST(BracesAroundStatementsCheckTest, If) { 172 EXPECT_NO_CHANGES(BracesAroundStatementsCheck, "int main() {\n" 173 " if (false) {\n" 174 " return -1;\n" 175 " }\n" 176 "}"); 177 EXPECT_NO_CHANGES(BracesAroundStatementsCheck, "int main() {\n" 178 " if (auto Cond = false) {\n" 179 " return -1;\n" 180 " }\n" 181 "}"); 182 EXPECT_NO_CHANGES(BracesAroundStatementsCheck, "int main() {\n" 183 " if (false) {\n" 184 " return -1;\n" 185 " } else {\n" 186 " return -2;\n" 187 " }\n" 188 "}"); 189 EXPECT_EQ("int main() {\n" 190 " if (false) {\n" 191 " return -1;\n" 192 "}\n" 193 "}", 194 runCheckOnCode<BracesAroundStatementsCheck>("int main() {\n" 195 " if (false)\n" 196 " return -1;\n" 197 "}")); 198 EXPECT_EQ("int main() {\n" 199 " if (auto Cond = false /**/ ) {\n" 200 " return -1;\n" 201 "}\n" 202 "}", 203 runCheckOnCode<BracesAroundStatementsCheck>( 204 "int main() {\n" 205 " if (auto Cond = false /**/ )\n" 206 " return -1;\n" 207 "}")); 208 // FIXME: Consider adding braces before EMPTY_MACRO and after the statement. 209 EXPECT_NO_CHANGES(BracesAroundStatementsCheck, 210 "#define EMPTY_MACRO\n" 211 "int main() {\n" 212 " if (auto Cond = false EMPTY_MACRO /**/ ) EMPTY_MACRO\n" 213 " return -1;\n" 214 "}"); 215 EXPECT_EQ("int main() {\n" 216 " if (true) { return -1/**/ ;\n" 217 "}\n" 218 "}", 219 runCheckOnCode<BracesAroundStatementsCheck>( 220 "int main() {\n" 221 " if (true) return -1/**/ ;\n" 222 "}")); 223 EXPECT_EQ("int main() {\n" 224 " if (false) {\n" 225 " return -1;\n" 226 " } else {\n" 227 " return -2;\n" 228 "}\n" 229 "}", 230 runCheckOnCode<BracesAroundStatementsCheck>("int main() {\n" 231 " if (false)\n" 232 " return -1;\n" 233 " else\n" 234 " return -2;\n" 235 "}")); 236 EXPECT_EQ("int main() {\n" 237 " if (false) {\n" 238 " return -1;\n" 239 " } else if (1 == 2) {\n" 240 " return -2;\n" 241 " } else {\n" 242 " return -3;\n" 243 "}\n" 244 "}", 245 runCheckOnCode<BracesAroundStatementsCheck>("int main() {\n" 246 " if (false)\n" 247 " return -1;\n" 248 " else if (1 == 2)\n" 249 " return -2;\n" 250 " else\n" 251 " return -3;\n" 252 "}")); 253 EXPECT_EQ("int main() {\n" 254 " if (false) {\n" 255 " return -1;\n" 256 " } else if (1 == 2) {\n" 257 " return -2;\n" 258 " } else {\n" 259 " return -3;\n" 260 "}\n" 261 "}", 262 runCheckOnCode<BracesAroundStatementsCheck>("int main() {\n" 263 " if (false)\n" 264 " return -1;\n" 265 " else if (1 == 2) {\n" 266 " return -2;\n" 267 " } else\n" 268 " return -3;\n" 269 "}")); 270 } 271 272 TEST(BracesAroundStatementsCheckTest, IfElseWithShortStatements) { 273 ClangTidyOptions Options; 274 Options.CheckOptions["test-check-0.ShortStatementLines"] = "1"; 275 276 EXPECT_EQ("int main() {\n" 277 " if (true) return 1;\n" 278 " if (false) { return -1;\n" 279 " } else if (1 == 2) { return -2;\n" 280 " } else { return -3;\n" 281 "}\n" 282 "}", 283 runCheckOnCode<BracesAroundStatementsCheck>( 284 "int main() {\n" 285 " if (true) return 1;\n" 286 " if (false) return -1;\n" 287 " else if (1 == 2) return -2;\n" 288 " else return -3;\n" 289 "}", 290 nullptr, "input.cc", None, Options)); 291 292 // If the last else is an else-if, we also force it. 293 EXPECT_EQ("int main() {\n" 294 " if (false) { return -1;\n" 295 " } else if (1 == 2) { return -2;\n" 296 "}\n" 297 "}", 298 runCheckOnCode<BracesAroundStatementsCheck>( 299 "int main() {\n" 300 " if (false) return -1;\n" 301 " else if (1 == 2) return -2;\n" 302 "}", 303 nullptr, "input.cc", None, Options)); 304 } 305 306 TEST(BracesAroundStatementsCheckTest, For) { 307 EXPECT_NO_CHANGES(BracesAroundStatementsCheck, "int main() {\n" 308 " for (;;) {\n" 309 " ;\n" 310 " }\n" 311 "}"); 312 EXPECT_EQ("int main() {\n" 313 " for (;;) {\n" 314 " ;\n" 315 "}\n" 316 "}", 317 runCheckOnCode<BracesAroundStatementsCheck>("int main() {\n" 318 " for (;;)\n" 319 " ;\n" 320 "}")); 321 EXPECT_EQ("int main() {\n" 322 " for (;;) {\n" 323 " /**/ ;\n" 324 "}\n" 325 "}", 326 runCheckOnCode<BracesAroundStatementsCheck>("int main() {\n" 327 " for (;;)\n" 328 " /**/ ;\n" 329 "}")); 330 EXPECT_EQ("int main() {\n" 331 " for (;;) {\n" 332 " return -1 /**/ ;\n" 333 "}\n" 334 "}", 335 runCheckOnCode<BracesAroundStatementsCheck>("int main() {\n" 336 " for (;;)\n" 337 " return -1 /**/ ;\n" 338 "}")); 339 } 340 341 TEST(BracesAroundStatementsCheckTest, ForRange) { 342 EXPECT_NO_CHANGES(BracesAroundStatementsCheck, "int main() {\n" 343 " int arr[4];\n" 344 " for (int i : arr) {\n" 345 " ;\n" 346 " }\n" 347 "}"); 348 EXPECT_EQ("int main() {\n" 349 " int arr[4];\n" 350 " for (int i : arr) {\n" 351 " ;\n" 352 "}\n" 353 " for (int i : arr) {\n" 354 " return -1 ;\n" 355 "}\n" 356 "}", 357 runCheckOnCode<BracesAroundStatementsCheck>("int main() {\n" 358 " int arr[4];\n" 359 " for (int i : arr)\n" 360 " ;\n" 361 " for (int i : arr)\n" 362 " return -1 ;\n" 363 "}")); 364 } 365 366 TEST(BracesAroundStatementsCheckTest, DoWhile) { 367 EXPECT_NO_CHANGES(BracesAroundStatementsCheck, "int main() {\n" 368 " do {\n" 369 " ;\n" 370 " } while (false);\n" 371 "}"); 372 EXPECT_EQ("int main() {\n" 373 " do {\n" 374 " ;\n" 375 " } while (false);\n" 376 "}", 377 runCheckOnCode<BracesAroundStatementsCheck>("int main() {\n" 378 " do\n" 379 " ;\n" 380 " while (false);\n" 381 "}")); 382 } 383 384 TEST(BracesAroundStatementsCheckTest, While) { 385 EXPECT_NO_CHANGES(BracesAroundStatementsCheck, "int main() {\n" 386 " while (false) {\n" 387 " ;\n" 388 " }\n" 389 "}"); 390 EXPECT_EQ("int main() {\n" 391 " while (false) {\n" 392 " ;\n" 393 "}\n" 394 "}", 395 runCheckOnCode<BracesAroundStatementsCheck>("int main() {\n" 396 " while (false)\n" 397 " ;\n" 398 "}")); 399 EXPECT_EQ("int main() {\n" 400 " while (auto Cond = false) {\n" 401 " ;\n" 402 "}\n" 403 "}", 404 runCheckOnCode<BracesAroundStatementsCheck>( 405 "int main() {\n" 406 " while (auto Cond = false)\n" 407 " ;\n" 408 "}")); 409 EXPECT_EQ("int main() {\n" 410 " while (false /*dummy token*/) {\n" 411 " ;\n" 412 "}\n" 413 "}", 414 runCheckOnCode<BracesAroundStatementsCheck>( 415 "int main() {\n" 416 " while (false /*dummy token*/)\n" 417 " ;\n" 418 "}")); 419 EXPECT_EQ("int main() {\n" 420 " while (false) {\n" 421 " break;\n" 422 "}\n" 423 "}", 424 runCheckOnCode<BracesAroundStatementsCheck>("int main() {\n" 425 " while (false)\n" 426 " break;\n" 427 "}")); 428 EXPECT_EQ("int main() {\n" 429 " while (false) {\n" 430 " break /**/;\n" 431 "}\n" 432 "}", 433 runCheckOnCode<BracesAroundStatementsCheck>("int main() {\n" 434 " while (false)\n" 435 " break /**/;\n" 436 "}")); 437 EXPECT_EQ("int main() {\n" 438 " while (false) {\n" 439 " /**/;\n" 440 "}\n" 441 "}", 442 runCheckOnCode<BracesAroundStatementsCheck>("int main() {\n" 443 " while (false)\n" 444 " /**/;\n" 445 "}")); 446 } 447 448 TEST(BracesAroundStatementsCheckTest, Nested) { 449 EXPECT_EQ("int main() {\n" 450 " do { if (true) {}} while (false);\n" 451 "}", 452 runCheckOnCode<BracesAroundStatementsCheck>( 453 "int main() {\n" 454 " do if (true) {}while (false);\n" 455 "}")); 456 EXPECT_EQ("int main() {\n" 457 " do { if (true) {}} while (false);\n" 458 "}", 459 runCheckOnCode<BracesAroundStatementsCheck>( 460 "int main() {\n" 461 " do if (true) {}while (false);\n" 462 "}")); 463 EXPECT_EQ( 464 "int main() {\n" 465 " if (true) {\n" 466 " // comment\n" 467 " if (false) {\n" 468 " // comment\n" 469 " /**/ ; // comment\n" 470 " }\n" 471 "}\n" 472 "}", 473 runCheckOnCode<BracesAroundStatementsCheck>("int main() {\n" 474 " if (true)\n" 475 " // comment\n" 476 " if (false) {\n" 477 " // comment\n" 478 " /**/ ; // comment\n" 479 " }\n" 480 "}")); 481 } 482 483 TEST(BracesAroundStatementsCheckTest, Macros) { 484 EXPECT_NO_CHANGES(BracesAroundStatementsCheck, 485 "#define IF(COND) if (COND) return -1;\n" 486 "int main() {\n" 487 " IF(false)\n" 488 "}"); 489 EXPECT_NO_CHANGES(BracesAroundStatementsCheck, 490 "#define FOR(COND) for (COND) return -1;\n" 491 "int main() {\n" 492 " FOR(;;)\n" 493 "}"); 494 EXPECT_EQ("#define DO_IT ++i\n" 495 "int i = 0;\n" 496 "int main() {\n" 497 " if (false) {\n" 498 " DO_IT;\n" 499 " } else if (1 == 2) {\n" 500 " DO_IT;\n" 501 " } else {\n" 502 " DO_IT;\n" 503 "}\n" 504 "}", 505 runCheckOnCode<BracesAroundStatementsCheck>("#define DO_IT ++i\n" 506 "int i = 0;\n" 507 "int main() {\n" 508 " if (false)\n" 509 " DO_IT;\n" 510 " else if (1 == 2)\n" 511 " DO_IT;\n" 512 " else\n" 513 " DO_IT;\n" 514 "}")); 515 } 516 517 #define EXPECT_NO_CHANGES_WITH_OPTS(Check, Opts, Code) \ 518 EXPECT_EQ(Code, runCheckOnCode<Check>(Code, nullptr, "input.cc", None, Opts)) 519 TEST(BracesAroundStatementsCheckTest, ImplicitCastInReturn) { 520 ClangTidyOptions Opts; 521 Opts.CheckOptions["test-check-0.ShortStatementLines"] = "1"; 522 523 StringRef Input = "const char *f() {\n" 524 " if (true) return \"\";\n" 525 " return \"abc\";\n" 526 "}\n"; 527 EXPECT_NO_CHANGES_WITH_OPTS(BracesAroundStatementsCheck, Opts, Input); 528 EXPECT_EQ("const char *f() {\n" 529 " if (true) { return \"\";\n" 530 "}\n" 531 " return \"abc\";\n" 532 "}\n", 533 runCheckOnCode<BracesAroundStatementsCheck>(Input)); 534 } 535 536 } // namespace test 537 } // namespace tidy 538 } // namespace clang 539