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