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