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