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