]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/testsuite/c-c++-common/Wmisleading-indentation.c
Implement -Wmisleading-indentation
[thirdparty/gcc.git] / gcc / testsuite / c-c++-common / Wmisleading-indentation.c
1 /* { dg-options "-Wmisleading-indentation -Wall" } */
2 /* { dg-do compile } */
3
4 extern int foo (int);
5 extern int bar (int, int);
6 extern int flagA;
7 extern int flagB;
8 extern int flagC;
9 extern int flagD;
10
11 int
12 fn_1 (int flag)
13 {
14 int x = 4, y = 5;
15 if (flag) /* { dg-message "3: ...this 'if' clause, but it is not" } */
16 x = 3;
17 y = 2; /* { dg-warning "statement is indented as if it were guarded by..." } */
18 return x * y;
19 }
20
21 int
22 fn_2 (int flag, int x, int y)
23 {
24 if (flag) /* { dg-message "3: ...this 'if' clause, but it is not" } */
25 x++; y++; /* { dg-warning "statement is indented as if it were guarded by..." } */
26
27 return x * y;
28 }
29
30 int
31 fn_3 (int flag)
32 {
33 int x = 4, y = 5;
34 if (flag)
35 x = 3;
36 else /* { dg-message "3: ...this 'else' clause, but it is not" } */
37 x = 2;
38 y = 2; /* { dg-warning "statement is indented as if it were guarded by..." } */
39 return x * y;
40 }
41
42 void
43 fn_4 (double *a, double *b, double *c)
44 {
45 int i = 0;
46 while (i < 10) /* { dg-message "3: ...this 'while' clause, but it is not" } */
47 a[i] = b[i] * c[i];
48 i++; /* { dg-warning "statement is indented as if it were guarded by..." } */
49 }
50
51 void
52 fn_5 (double *a, double *b, double *sum, double *prod)
53 {
54 int i = 0;
55 for (i = 0; i < 10; i++) /* { dg-output "3: ...this 'for' clause, but it is not" } */
56 sum[i] = a[i] * b[i];
57 prod[i] = a[i] * b[i]; /* { dg-warning "statement is indented as if it were guarded by..." } */
58 }
59
60 /* Based on CVE-2014-1266 aka "goto fail" */
61 int fn_6 (int a, int b, int c)
62 {
63 int err;
64
65 /* ... */
66 if ((err = foo (a)) != 0)
67 goto fail;
68 if ((err = foo (b)) != 0) /* { dg-message "2: ...this 'if' clause, but it is not" } */
69 goto fail;
70 goto fail; /* { dg-warning "statement is indented as if it were guarded by..." } */
71 if ((err = foo (c)) != 0)
72 goto fail;
73 /* ... */
74
75 fail:
76 return err;
77 }
78
79 int fn_7 (int p, int q, int r, int s, int t)
80 {
81 if (bar (p, q))
82 {
83 if (p) /* { dg-message "7: ...this 'if' clause, but it is not" } */
84 q++; r++; /* { dg-warning "statement is indented as if it were guarded by..." } */
85 t++;
86 }
87 return p + q + r + s + t;
88 }
89
90 int fn_8 (int a, int b, int c)
91 {
92 /* This should *not* be flagged as misleading indentation. */
93 if (a) return b; else return c;
94 }
95
96 void fn_9 (int flag)
97 {
98 if (flag) /* { dg-message "3: ...this 'if' clause, but it is not" } */
99 foo (0);
100 foo (1); /* { dg-warning "statement is indented as if it were guarded by..." } */
101 }
102
103 void fn_10 (int flag)
104 {
105 if (flag) /* { dg-message "3: ...this 'if' clause, but it is not" } */
106 if (flag / 2)
107 {
108 foo (0);
109 foo (1);
110 }
111 foo (2); /* { dg-warning "statement is indented as if it were guarded by..." } */
112 foo (3);
113 }
114
115 void fn_11 (void)
116 {
117 if (flagA)
118 if (flagB)
119 if (flagC) /* { dg-message "7: ...this 'if' clause, but it is not" } */
120 foo (0);
121 bar (1, 2); /* { dg-warning "statement is indented as if it were guarded by..." } */
122 }
123
124 void fn_12 (void)
125 {
126 if (flagA)
127 if (flagB) /* { dg-message "5: ...this 'if' clause, but it is not" } */
128 if (flagC)
129 foo (0);
130 bar (1, 2); /* { dg-warning "statement is indented as if it were guarded by..." } */
131 }
132
133 void fn_13 (void)
134 {
135 if (flagA) /* { dg-message "3: ...this 'if' clause, but it is not" } */
136 if (flagB)
137 if (flagC)
138 foo (0);
139 bar (1, 2); /* { dg-warning "statement is indented as if it were guarded by..." } */
140 }
141
142 #define FOR_EACH(VAR, START, STOP) \
143 for ((VAR) = (START); (VAR) < (STOP); (VAR++)) /* { dg-message "3: ...this 'for' clause, but it is not" } */
144
145 void fn_14 (void)
146 {
147 int i;
148 FOR_EACH (i, 0, 10) /* { dg-message "3: in expansion of macro" } */
149 foo (i);
150 bar (i, i); /* { dg-warning "statement is indented as if it were guarded by..." } */
151 }
152 #undef FOR_EACH
153
154 #define FOR_EACH(VAR, START, STOP) for ((VAR) = (START); (VAR) < (STOP); (VAR++)) /* { dg-message "36: ...this 'for' clause, but it is not" } */
155 void fn_15 (void)
156 {
157 int i;
158 FOR_EACH (i, 0, 10) /* { dg-message "3: in expansion of macro" } */
159 foo (i);
160 bar (i, i); /* { dg-warning "statement is indented as if it were guarded by..." } */
161 }
162 #undef FOR_EACH
163
164 void fn_16_spaces (void)
165 {
166 int i;
167 for (i = 0; i < 10; i++)
168 while (flagA)
169 if (flagB) /* { dg-message "7: ...this 'if' clause, but it is not" } */
170 foo (0);
171 foo (1); /* { dg-warning "statement is indented as if it were guarded by..." } */
172 }
173
174 void fn_16_tabs (void)
175 {
176 int i;
177 for (i = 0; i < 10; i++)
178 while (flagA)
179 if (flagB) /* { dg-message "7: ...this 'if' clause, but it is not" } */
180 foo (0);
181 foo (1);/* { dg-warning "statement is indented as if it were guarded by..." } */
182 }
183
184 void fn_17_spaces (void)
185 {
186 int i;
187 for (i = 0; i < 10; i++) /* { dg-message "3: ...this 'for' clause, but it is not" } */
188 while (flagA)
189 if (flagB)
190 foo (0);
191 foo (1);/* { dg-warning "statement is indented as if it were guarded by..." } */
192 }
193
194 void fn_17_tabs (void)
195 {
196 int i;
197 for (i = 0; i < 10; i++) /* { dg-message "3: ...this 'for' clause, but it is not" } */
198 while (flagA)
199 if (flagB)
200 foo (0);
201 foo (1);/* { dg-warning "statement is indented as if it were guarded by..." } */
202 }
203
204 void fn_18_spaces (void)
205 {
206 int i;
207 for (i = 0; i < 10; i++)
208 while (flagA) /* { dg-message "5: ...this 'while' clause, but it is not" } */
209 if (flagB)
210 foo (0);
211 foo (1);/* { dg-warning "statement is indented as if it were guarded by..." } */
212 }
213
214 void fn_18_tabs (void)
215 {
216 int i;
217 for (i = 0; i < 10; i++)
218 while (flagA) /* { dg-message "5: ...this 'while' clause, but it is not" } */
219 if (flagB)
220 foo (0);
221 foo (1);/* { dg-warning "statement is indented as if it were guarded by..." } */
222 }
223
224 /* This shouldn't lead to a warning. */
225 int fn_19 (void) { if (flagA) return 1; else return 0; }
226
227 /* A deeply-nested mixture of spaces and tabs, adapted from
228 c-c++-common/pr60101.c.
229 This should not lead to a warning. */
230 void
231 fn_20 (unsigned int l)
232 {
233 unsigned int i;
234
235 for (i = 0; i < 10; i++)
236 {
237 unsigned int n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11;
238
239 for (n0 = 0; n0 < l; n0++)
240 for (n1 = 0; n1 < l; n1++)
241 for (n2 = 0; n2 < l; n2++)
242 for (n3 = 0; n3 < l; n3++)
243 for (n4 = 0; n4 < l; n4++)
244 for (n5 = 0; n5 < l; n5++)
245 for (n6 = 0; n6 < l; n6++)
246 for (n7 = 0; n7 < l; n7++)
247 for (n8 = 0; n8 < l; n8++)
248 for (n9 = 0; n9 < l; n9++)
249 for (n10 = 0; n10 < l; n10++)
250 for (n11 = 0; n11 < l; n11++)
251 {
252 if (flagA)
253 foo (0);
254 foo (1);
255 }
256 foo (2);
257 }
258 }
259
260 /* Another nested mix of tabs and spaces that shouldn't lead to a warning,
261 with a preprocessor directive thrown in for good measure
262 (adapted from libgomp/loop.c: gomp_loop_init). */
263 void fn_21 (void)
264 {
265 foo (0);
266 if (flagA)
267 {
268 foo (1);
269
270 #if 1
271 {
272 foo (2);
273 if (flagB)
274 {
275 if (flagC)
276 foo (3);
277 else
278 foo (4);
279 }
280 else if (flagD)
281 foo (5);
282 else
283 foo (6);
284 }
285 #endif
286 }
287 }
288
289 /* The conditionals within the following macros shouldn't be warned about.
290 Adapted from libgomp/driver.c: gomp_load_plugin_for_device. */
291 int fn_22 (void)
292 {
293 int err = 0;
294
295 #define DLSYM() \
296 do \
297 { \
298 err = foo (0); \
299 if (err) \
300 goto out; \
301 } \
302 while (0)
303 #define DLSYM_OPT() \
304 do \
305 { \
306 err = foo (1); \
307 if (err) \
308 foo (2); \
309 else \
310 foo (3); \
311 foo (4); \
312 } \
313 while (0)
314 DLSYM ();
315 DLSYM_OPT ();
316 #undef DLSYM
317 #undef DLSYM_OPT
318
319 out:
320 return err;
321 }
322
323 /* This shouldn't be warned about. */
324 void fn_23 (void) { foo (0); foo (1); if (flagA) foo (2); foo (3); foo (4); }
325
326 /* Code that simply doesn't bother indenting anywhere (e.g. autogenerated
327 code) shouldn't be warned about. */
328 void fn_24 (void)
329 {
330 foo (0);
331 if (flagA)
332 foo (1);
333 foo (2);
334 }
335
336 /* Adapted from libiberty/regex.c; an example of a conditional in a
337 macro where the successor statement begins with a macro arg:
338
339 if (num < 0)
340 num = 0;
341 num = num * 10 + c - '0';
342 ^ this successor statement
343
344 and hence "num" has a spelling location at the argument of the
345 macro usage site ("lower_bound"), we want the definition of the
346 parameter ("num") for the indentation comparison to be meaninful.
347
348 This should not generate a misleading indentation warning. */
349
350 # define GET_UNSIGNED_NUMBER(num) \
351 { \
352 while (flagA) \
353 { \
354 if (flagB) \
355 { \
356 if (num < 0) \
357 num = 0; \
358 num = num * 10 + c - '0'; \
359 } \
360 } \
361 }
362 void fn_25 (int c, int lower_bound, int upper_bound)
363 {
364 GET_UNSIGNED_NUMBER (lower_bound);
365 }
366 #undef GET_UNSIGNED_NUMBER
367
368 /* Example adapted from libdecnumber/decNumber.c:decExpOp that shouldn't
369 trigger a warning. */
370 void fn_26 (void)
371 {
372 if (flagA) {
373 if (flagB) foo (0); }
374 foo (1);
375 }
376
377 /* Ensure that we don't get confused by mixed tabs and spaces; the line
378 "foo (1);" has leading spaces before a tab, but this should not
379 lead to a warning from -Wmisleading-indentation. */
380 void fn_27 (void)
381 {
382 if (flagA)
383 foo (0);
384 foo (1);
385 }
386
387 /* Example adapted from gcc/cgraph.h:symtab_node::get_availability of
388 a spurious trailing semicolon that shouldn't generate a warning. */
389 void fn_28 (void)
390 {
391 if (flagA)
392 foo (0);
393 else
394 foo (1);;
395 }
396
397 /* However, other kinds of spurious semicolons can be a problem. Sadly
398 we don't yet report for the misleading-indented "foo (1);" in the
399 following, due to the spurious semicolon. */
400 void fn_29 (void)
401 {
402 if (flagA)
403 if (flagB)
404 foo (0);;
405 foo (1);
406 }
407
408 /* Adapted from usage site of #ifdef HAVE_cc0. This should not lead
409 to a warning from -Wmisleading-indentation. */
410 void fn_30 (void)
411 {
412 if (flagA)
413 foo (0);
414 #if SOME_CONDITION_THAT_DOES_NOT_HOLD
415 if (flagB)
416 #endif
417 foo (1);
418 }
419
420 /* This shouldn't lead to a warning. */
421 void fn_31 (void)
422 {
423 if (flagA)
424 foo (0);
425 else if (flagB)
426 foo (1);
427 else if (flagC)
428 foo (2);
429 else
430 foo (3);
431 }