xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/readability/misleading-indentation.cpp (revision 72390c5c56c5f6a2c2d55231d96f03471eee8cb4)
1 // RUN: %check_clang_tidy %s readability-misleading-indentation %t -- -- -fno-delayed-template-parsing
2 
3 void foo1();
4 void foo2();
5 void foo3();
6 
7 #define E
8 
9 #define BLOCK \
10   if (cond1)  \
11     foo1();   \
12     foo2();
13 
f()14 void f()
15 {
16   bool cond1 = true;
17   bool cond2 = true;
18 
19   if (cond1)
20     if (cond2)
21       foo1();
22   else
23     foo2();
24   // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: different indentation for 'if' and corresponding 'else' [readability-misleading-indentation]
25 
26   if (cond1) {
27     if (cond2)
28       foo1();
29   }
30   else
31     foo2();
32 
33   if (cond1)
34     if (cond2)
35       foo1();
36     else
37       foo2();
38 
39   if (cond2)
40     foo1();
41     foo2();
42     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: misleading indentation: statement is indented too deeply [readability-misleading-indentation]
43     // CHECK-MESSAGES: :[[@LINE-4]]:3: note: did you mean this line to be inside this 'if'
44     foo2(); // No redundant warning.
45 
46   if (cond1)
47   {
48     foo1();
49   }
50     foo2();
51 
52   if (cond1)
53     foo1();
54   foo2();
55 
56   if (cond2)
57     if (cond1) foo1(); else foo2();
58 
59   if (cond1) {
60   } else {
61   }
62 
63   if (cond1) {
64   }
65   else {
66   }
67 
68   if (cond1)
69   {
70   }
71   else
72   {
73   }
74 
75   if (cond1)
76     {
77     }
78   else
79     {
80     }
81 
82   if(cond1) {
83   }
84   else if (cond2) {
85   }
86   else {
87   }
88 
89   if(cond1) {
90   }
91   else if (cond2) {
92   }
93        else {
94   }
95   // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: different indentation for 'if' and corresponding 'else' [readability-misleading-indentation]
96 
97   if (cond1) {
98     if (cond1) {
99     }
100     else if (cond2) {
101     }
102     else {
103     }
104     if (cond1) {
105     } else if (cond2) {
106     } else if (!cond2) {
107     } else {
108     }
109   }
110   else if (cond2) {
111   }
112 
113   BLOCK
114 
115   if (cond1)
116     foo1();
117   else
118     foo2();
119   E foo3();
120   // CHECK-MESSAGES-NOT: :[[@LINE-1]]readability-misleading-indentation
121 }
122 
g(bool x)123 void g(bool x) {
124   if (x)
125     #pragma unroll
126     for (int k = 0; k < 1; ++k) {}
127 
128   #pragma unroll
129   for (int k = 0; k < 1; ++k) {}
130 }
131 
132 template<bool b>
mustPass()133 void mustPass() {
134   if constexpr (b) {
135     foo1();
136   } else {
137     foo2();
138   }
139 }
140 
mustPassNonTemplate()141 void mustPassNonTemplate() {
142   constexpr unsigned Value = 1;
143   if constexpr (Value == 0) {
144     foo1();
145   } else if constexpr (Value == 1) {
146     foo2();
147   } else {
148     foo3();
149   }
150 }
151 
152 template<bool b>
mustFail()153 void mustFail() {
154   if constexpr (b) {
155     foo1();
156   }
157     else {
158       foo2();
159       // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: different indentation for 'if' and corresponding 'else' [readability-misleading-indentation]
160   }
161 }
162 
mustFailNonTemplate()163 void mustFailNonTemplate() {
164   constexpr unsigned Value = 1;
165   if constexpr (Value == 0) {
166     foo1();
167   }
168     else {
169   foo2();
170   // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: different indentation for 'if' and corresponding 'else' [readability-misleading-indentation]
171   }
172 
173   if constexpr (Value == 0)
174     foo1();
175     else
176   foo2();
177   // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: different indentation for 'if' and corresponding 'else' [readability-misleading-indentation]
178 }
179 
180 template<bool b>
mustFailNoInsta()181 void mustFailNoInsta() {
182   if constexpr (b) {
183     foo1();
184   }
185     else {
186       foo2();
187       // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: different indentation for 'if' and corresponding 'else' [readability-misleading-indentation]
188   }
189 }
190 
191 template<bool b>
mustPassNoInsta()192 void mustPassNoInsta() {
193   if constexpr (b) {
194     foo1();
195   }
196   else {
197     foo2();
198   }
199 }
200 
call()201 void call() {
202   mustPass<true>();
203   mustPass<false>();
204   mustFail<true>();
205   mustFail<false>();
206 }
207