Implement -Wmisleading-indentation
[official-gcc.git] / gcc / testsuite / c-c++-common / Wmisleading-indentation.c
blob3dbbb8b17d3554c6d8fa0223685b07042f51443e
1 /* { dg-options "-Wmisleading-indentation -Wall" } */
2 /* { dg-do compile } */
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;
11 int
12 fn_1 (int flag)
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;
21 int
22 fn_2 (int flag, int x, int y)
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..." } */
27 return x * y;
30 int
31 fn_3 (int flag)
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;
42 void
43 fn_4 (double *a, double *b, double *c)
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..." } */
51 void
52 fn_5 (double *a, double *b, double *sum, double *prod)
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..." } */
60 /* Based on CVE-2014-1266 aka "goto fail" */
61 int fn_6 (int a, int b, int c)
63 int err;
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 /* ... */
75 fail:
76 return err;
79 int fn_7 (int p, int q, int r, int s, int t)
81 if (bar (p, q))
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++;
87 return p + q + r + s + t;
90 int fn_8 (int a, int b, int c)
92 /* This should *not* be flagged as misleading indentation. */
93 if (a) return b; else return c;
96 void fn_9 (int flag)
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..." } */
103 void fn_10 (int flag)
105 if (flag) /* { dg-message "3: ...this 'if' clause, but it is not" } */
106 if (flag / 2)
108 foo (0);
109 foo (1);
111 foo (2); /* { dg-warning "statement is indented as if it were guarded by..." } */
112 foo (3);
115 void fn_11 (void)
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..." } */
124 void fn_12 (void)
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..." } */
133 void fn_13 (void)
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..." } */
142 #define FOR_EACH(VAR, START, STOP) \
143 for ((VAR) = (START); (VAR) < (STOP); (VAR++)) /* { dg-message "3: ...this 'for' clause, but it is not" } */
145 void fn_14 (void)
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..." } */
152 #undef FOR_EACH
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)
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..." } */
162 #undef FOR_EACH
164 void fn_16_spaces (void)
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..." } */
174 void fn_16_tabs (void)
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..." } */
184 void fn_17_spaces (void)
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..." } */
194 void fn_17_tabs (void)
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..." } */
204 void fn_18_spaces (void)
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..." } */
214 void fn_18_tabs (void)
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..." } */
224 /* This shouldn't lead to a warning. */
225 int fn_19 (void) { if (flagA) return 1; else return 0; }
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)
233 unsigned int i;
235 for (i = 0; i < 10; i++)
237 unsigned int n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11;
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++)
252 if (flagA)
253 foo (0);
254 foo (1);
256 foo (2);
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)
265 foo (0);
266 if (flagA)
268 foo (1);
270 #if 1
272 foo (2);
273 if (flagB)
275 if (flagC)
276 foo (3);
277 else
278 foo (4);
280 else if (flagD)
281 foo (5);
282 else
283 foo (6);
285 #endif
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)
293 int err = 0;
295 #define DLSYM() \
296 do \
298 err = foo (0); \
299 if (err) \
300 goto out; \
302 while (0)
303 #define DLSYM_OPT() \
304 do \
306 err = foo (1); \
307 if (err) \
308 foo (2); \
309 else \
310 foo (3); \
311 foo (4); \
313 while (0)
314 DLSYM ();
315 DLSYM_OPT ();
316 #undef DLSYM
317 #undef DLSYM_OPT
319 out:
320 return err;
323 /* This shouldn't be warned about. */
324 void fn_23 (void) { foo (0); foo (1); if (flagA) foo (2); foo (3); foo (4); }
326 /* Code that simply doesn't bother indenting anywhere (e.g. autogenerated
327 code) shouldn't be warned about. */
328 void fn_24 (void)
330 foo (0);
331 if (flagA)
332 foo (1);
333 foo (2);
336 /* Adapted from libiberty/regex.c; an example of a conditional in a
337 macro where the successor statement begins with a macro arg:
339 if (num < 0)
340 num = 0;
341 num = num * 10 + c - '0';
342 ^ this successor statement
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.
348 This should not generate a misleading indentation warning. */
350 # define GET_UNSIGNED_NUMBER(num) \
352 while (flagA) \
354 if (flagB) \
356 if (num < 0) \
357 num = 0; \
358 num = num * 10 + c - '0'; \
362 void fn_25 (int c, int lower_bound, int upper_bound)
364 GET_UNSIGNED_NUMBER (lower_bound);
366 #undef GET_UNSIGNED_NUMBER
368 /* Example adapted from libdecnumber/decNumber.c:decExpOp that shouldn't
369 trigger a warning. */
370 void fn_26 (void)
372 if (flagA) {
373 if (flagB) foo (0); }
374 foo (1);
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)
382 if (flagA)
383 foo (0);
384 foo (1);
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)
391 if (flagA)
392 foo (0);
393 else
394 foo (1);;
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)
402 if (flagA)
403 if (flagB)
404 foo (0);;
405 foo (1);
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)
412 if (flagA)
413 foo (0);
414 #if SOME_CONDITION_THAT_DOES_NOT_HOLD
415 if (flagB)
416 #endif
417 foo (1);
420 /* This shouldn't lead to a warning. */
421 void fn_31 (void)
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);