/* { dg-options "-Wmisleading-indentation -Wall" } */ /* { dg-do compile } */ extern int foo (int); extern int bar (int, int); extern int flagA; extern int flagB; extern int flagC; extern int flagD; int fn_1 (int flag) { int x = 4, y = 5; if (flag) /* { dg-warning "3: this 'if' clause does not guard..." } */ x = 3; y = 2; /* { dg-message "5: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'" } */ return x * y; } int fn_2 (int flag, int x, int y) { if (flag) /* { dg-warning "3: this 'if' clause does not guard..." } */ x++; y++; /* { dg-message "10: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'" } */ return x * y; } int fn_3 (int flag) { int x = 4, y = 5; if (flag) x = 3; else /* { dg-warning "3: this 'else' clause does not guard..." } */ x = 2; y = 2; /* { dg-message "5: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'else'" } */ return x * y; } void fn_4 (double *a, double *b, double *c) { int i = 0; while (i < 10) /* { dg-warning "3: this 'while' clause does not guard..." } */ a[i] = b[i] * c[i]; i++; /* { dg-message "5: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'while'" } */ } void fn_5 (double *a, double *b, double *sum, double *prod) { int i = 0; for (i = 0; i < 10; i++) /* { dg-warning "3: this 'for' clause does not guard..." } */ sum[i] = a[i] * b[i]; prod[i] = a[i] * b[i]; /* { dg-message "5: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'" } */ } /* Based on CVE-2014-1266 aka "goto fail" */ int fn_6 (int a, int b, int c) { int err; /* ... */ if ((err = foo (a)) != 0) goto fail; if ((err = foo (b)) != 0) /* { dg-message "2: this 'if' clause does not guard..." } */ goto fail; goto fail; /* { dg-message "3: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'" } */ if ((err = foo (c)) != 0) goto fail; /* ... */ fail: return err; } int fn_7 (int p, int q, int r, int s, int t) { if (bar (p, q)) { if (p) /* { dg-message "7: this 'if' clause does not guard..." } */ q++; r++; /* { dg-message "14: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'" } */ t++; } return p + q + r + s + t; } int fn_8 (int a, int b, int c) { /* This should *not* be flagged as misleading indentation. */ if (a) return b; else return c; } void fn_9 (int flag) { if (flag) /* { dg-warning "3: this 'if' clause does not guard..." } */ foo (0); foo (1); /* { dg-message "5: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'" } */ } void fn_10 (int flag) { if (flag) /* { dg-warning "3: this 'if' clause does not guard..." } */ if (flag / 2) { foo (0); foo (1); } foo (2); /* { dg-message "5: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'" } */ foo (3); } void fn_11 (void) { if (flagA) if (flagB) if (flagC) /* { dg-message "7: this 'if' clause does not guard..." } */ foo (0); bar (1, 2); /* { dg-message "9: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'" } */ } void fn_12 (void) { if (flagA) if (flagB) /* { dg-message "5: this 'if' clause does not guard..." } */ if (flagC) foo (0); bar (1, 2); /* { dg-message "7: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'" } */ } void fn_13 (void) { if (flagA) /* { dg-warning "3: this 'if' clause does not guard..." } */ if (flagB) if (flagC) foo (0); bar (1, 2); /* { dg-message "5: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'" } */ } #define FOR_EACH(VAR, START, STOP) \ for ((VAR) = (START); (VAR) < (STOP); (VAR++)) /* { dg-warning "3: this 'for' clause does not guard..." } */ void fn_14 (void) { int i; FOR_EACH (i, 0, 10) /* { dg-message "in expansion of macro .FOR_EACH." } */ foo (i); bar (i, i); /* { dg-message "5: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'" } */ } #undef FOR_EACH #define FOR_EACH(VAR, START, STOP) for ((VAR) = (START); (VAR) < (STOP); (VAR++)) /* { dg-message "36: this 'for' clause does not guard..." } */ void fn_15 (void) { int i; FOR_EACH (i, 0, 10) /* { dg-message "in expansion of macro .FOR_EACH." } */ foo (i); bar (i, i); /* { dg-message "5: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'" } */ } #undef FOR_EACH void fn_16_spaces (void) { int i; for (i = 0; i < 10; i++) while (flagA) if (flagB) /* { dg-message "7: this 'if' clause does not guard..." } */ foo (0); foo (1); /* { dg-message "9: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'" } */ } void fn_16_tabs (void) { int i; for (i = 0; i < 10; i++) while (flagA) if (flagB) /* { dg-message "7: this 'if' clause does not guard..." } */ foo (0); foo (1);/* { dg-message "2: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'" } */ } void fn_17_spaces (void) { int i; for (i = 0; i < 10; i++) /* { dg-warning "3: this 'for' clause does not guard..." } */ while (flagA) if (flagB) foo (0); foo (1);/* { dg-message "5: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'" } */ } void fn_17_tabs (void) { int i; for (i = 0; i < 10; i++) /* { dg-warning "3: this 'for' clause does not guard..." } */ while (flagA) if (flagB) foo (0); foo (1);/* { dg-message "5: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'" } */ } void fn_18_spaces (void) { int i; for (i = 0; i < 10; i++) while (flagA) /* { dg-message "5: this 'while' clause does not guard..." } */ if (flagB) foo (0); foo (1);/* { dg-message "7: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'while'" } */ } void fn_18_tabs (void) { int i; for (i = 0; i < 10; i++) while (flagA) /* { dg-message "5: this 'while' clause does not guard..." } */ if (flagB) foo (0); foo (1);/* { dg-message "7: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'while'" } */ } /* This shouldn't lead to a warning. */ int fn_19 (void) { if (flagA) return 1; else return 0; } /* A deeply-nested mixture of spaces and tabs, adapted from c-c++-common/pr60101.c. This should not lead to a warning. */ void fn_20 (unsigned int l) { unsigned int i; for (i = 0; i < 10; i++) { unsigned int n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11; for (n0 = 0; n0 < l; n0++) for (n1 = 0; n1 < l; n1++) for (n2 = 0; n2 < l; n2++) for (n3 = 0; n3 < l; n3++) for (n4 = 0; n4 < l; n4++) for (n5 = 0; n5 < l; n5++) for (n6 = 0; n6 < l; n6++) for (n7 = 0; n7 < l; n7++) for (n8 = 0; n8 < l; n8++) for (n9 = 0; n9 < l; n9++) for (n10 = 0; n10 < l; n10++) for (n11 = 0; n11 < l; n11++) { if (flagA) foo (0); foo (1); } foo (2); } } /* Another nested mix of tabs and spaces that shouldn't lead to a warning, with a preprocessor directive thrown in for good measure (adapted from libgomp/loop.c: gomp_loop_init). */ void fn_21 (void) { foo (0); if (flagA) { foo (1); #if 1 { foo (2); if (flagB) { if (flagC) foo (3); else foo (4); } else if (flagD) foo (5); else foo (6); } #endif } } /* The conditionals within the following macros shouldn't be warned about. Adapted from libgomp/driver.c: gomp_load_plugin_for_device. */ int fn_22 (void) { int err = 0; #define DLSYM() \ do \ { \ err = foo (0); \ if (err) \ goto out; \ } \ while (0) #define DLSYM_OPT() \ do \ { \ err = foo (1); \ if (err) \ foo (2); \ else \ foo (3); \ foo (4); \ } \ while (0) DLSYM (); DLSYM_OPT (); #undef DLSYM #undef DLSYM_OPT out: return err; } /* This shouldn't be warned about. */ void fn_23 (void) { foo (0); foo (1); if (flagA) foo (2); foo (3); foo (4); } /* Code that simply doesn't bother indenting anywhere (e.g. autogenerated code) shouldn't be warned about. */ void fn_24 (void) { foo (0); if (flagA) foo (1); foo (2); } /* Adapted from libiberty/regex.c; an example of a conditional in a macro where the successor statement begins with a macro arg: if (num < 0) num = 0; num = num * 10 + c - '0'; ^ this successor statement and hence "num" has a spelling location at the argument of the macro usage site ("lower_bound"), we want the definition of the parameter ("num") for the indentation comparison to be meaninful. This should not generate a misleading indentation warning. */ # define GET_UNSIGNED_NUMBER(num) \ { \ while (flagA) \ { \ if (flagB) \ { \ if (num < 0) \ num = 0; \ num = num * 10 + c - '0'; \ } \ } \ } void fn_25 (int c, int lower_bound, int upper_bound) { GET_UNSIGNED_NUMBER (lower_bound); } #undef GET_UNSIGNED_NUMBER /* Example adapted from libdecnumber/decNumber.c:decExpOp that shouldn't trigger a warning. */ void fn_26 (void) { if (flagA) { if (flagB) foo (0); } foo (1); } /* Ensure that we don't get confused by mixed tabs and spaces; the line "foo (1);" has leading spaces before a tab, but this should not lead to a warning from -Wmisleading-indentation. */ void fn_27 (void) { if (flagA) foo (0); foo (1); } /* Example adapted from gcc/cgraph.h:symtab_node::get_availability of a spurious trailing semicolon that shouldn't generate a warning. */ void fn_28 (void) { if (flagA) foo (0); else foo (1);; } /* However, other kinds of spurious semicolons can be a problem. Sadly we don't yet report for the misleading-indented "foo (1);" in the following, due to the spurious semicolon. */ void fn_29 (void) { if (flagA) if (flagB) foo (0);; foo (1); } /* Adapted from usage site of #ifdef HAVE_cc0. This should not lead to a warning from -Wmisleading-indentation. */ void fn_30 (void) { if (flagA) foo (0); #if SOME_CONDITION_THAT_DOES_NOT_HOLD if (flagB) #endif foo (1); } /* This shouldn't lead to a warning. */ void fn_31 (void) { if (flagA) foo (0); else if (flagB) foo (1); else if (flagC) foo (2); else foo (3); } /* Ensure that we can disable the warning. */ int fn_32 (int flag) { int x = 4, y = 5; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmisleading-indentation" if (flag) x = 3; y = 2; #pragma GCC diagnostic pop return x * y; } /* Verify that a variety of different indentation styles are supported without leading to warnings. */ void fn_33_k_and_r_style (void) { int i; for (i = 0; i < 10; i++) { if (flagB) { foo(0); foo(1); } else { foo(2); foo(3); } foo(4); } } void fn_33_stroustrup_style (void) { int i; for (i = 0; i < 10; i++) { if (flagA) { foo(0); foo(1); } else { foo(2); foo(3); } foo(4); } } void fn_33_allman_style (void) { int i; for (i = 0; i < 10; i++) { if (flagA) { foo(0); foo(1); } else { foo(2); foo(3); } foo(4); } } void fn_33_whitesmiths_style (void) { int i; for (i = 0; i < 10; i++) { if (flagA) { foo(0); foo(1); } else { foo(2); foo(3); } foo(4); } } void fn_33_horstmann_style (void) { int i; for (i = 0; i < 10; i++) { if (flagA) { foo(0); foo(1); } else { foo(2); foo(3); } foo(4); } } void fn_33_ratliff_banner_style (void) { int i; for (i = 0; i < 10; i++) { if (flagA) { foo(0); foo(1); } else { foo(2); foo(3); } foo(4); } } void fn_33_lisp_style (void) { int i; for (i = 0; i < 10; i++) { if (flagA) { foo(0); foo(1); } else { foo(2); foo(3); } foo(4); } } /* A function run through GNU "indent" with various options. None of these should lead to warnings. */ /* "indent -gnu". */ void fn_34_indent_dash_gnu (void) { int i; while (flagA) for (i = 0; i < 10; i++) { if (flagB) { foo (0); foo (1); } else { foo (2); foo (3); } foo (4); } foo (5); } /* "indent -kr". */ void fn_34_indent_dash_kr(void) { int i; while (flagA) for (i = 0; i < 10; i++) { if (flagB) { foo(0); foo(1); } else { foo(2); foo(3); } foo(4); } foo(5); } /* "indent -orig". */ void fn_34_indent_dash_orig(void) { int i; while (flagA) for (i = 0; i < 10; i++) { if (flagB) { foo(0); foo(1); } else { foo(2); foo(3); } foo(4); } foo(5); } /* Linux style: "indent \ -nbad -bap -nbc -bbo -hnl -br -brs -c33 -cd33 -ncdb -ce -ci4 \ -cli0 -d0 -di1 -nfc1 -i8 -ip0 -l80 -lp -npcs -nprs -npsl -sai \ -saf -saw -ncs -nsc -sob -nfca -cp33 -ss -ts8 -il1". */ void fn_34_indent_linux_style(void) { int i; while (flagA) for (i = 0; i < 10; i++) { if (flagB) { foo(0); foo(1); } else { foo(2); foo(3); } foo(4); } foo(5); } /* PR 66220. */ int fn_35 (int v) { int res = 28; if (v == 2) { res = 27; } else { res = 18; } return res; } /* This variant of K&R-style formatting (in the presence of conditional compilation) shouldn't lead to a warning. Based on false positive seen with r223098 when compiling linux-4.0.3:arch/x86/crypto/aesni-intel_glue.c:aesni_init. */ void fn_36 (void) { #if 1 /* e.g. some configuration variable. */ if (flagA) { foo(0); foo(1); foo(2); } else #endif { foo(3); foo(4); foo(5); } foo(6); /* We shouldn't warn here. */ } /* The following function contain code whose indentation is misleading, thus we warn about it. */ void fn_37 (void) { int i; #define EMPTY #define FOR_EACH(VAR, START, STOP) for (VAR = START; VAR < STOP; VAR++) /* { dg-warning "this 'for' clause" } */ while (flagA); /* { dg-warning "3: this 'while' clause" } */ foo (0); /* { dg-message "5: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'while'" } */ if (flagA) ; else if (flagB); /* { dg-warning "8: this 'if' clause" } */ foo (0); /* { dg-message "5: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'" } */ while (flagA) /* { dg-warning "3: this 'while' clause" } */ /* blah */; foo (0); /* { dg-message "5: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'while'" } */ if (flagA) ; else if (flagB) /* { dg-warning "8: this 'if' clause" } */ foo (1); foo (2); /* { dg-message "5: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'" } */ if (flagA) foo (1); else if (flagB) /* { dg-warning "8: this 'if' clause" } */ foo (2); foo (3); /* { dg-message "5: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'" } */ if (flagB) /* { dg-warning "3: this 'if' clause" } */ /* blah */; { /* { dg-message "5: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'" } */ foo (0); } if (flagB) /* { dg-warning "3: this 'if' clause" } */ /* blah */; { /* { dg-message "4: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'" } */ foo (0); } if (flagB) ; else; foo (0); /* { dg-warning "3: this 'else' clause" } */ if (flagC); foo (2); /* { dg-warning "3: this 'if' clause" } */ if (flagA) /* { dg-warning "3: this 'if' clause" } */ ; /* blah */ { /* { dg-message "18: ...this statement" } */ foo (1); } if (flagB) ; /* { dg-warning "3: this 'if' clause" } */ return; /* { dg-message "5: ...this statement" } */ if (flagB) EMPTY; /* { dg-warning "3: this 'if' clause" } */ foo (1); /* { dg-message "5: ...this statement" } */ for (i = 0; i < 10; i++); /* { dg-warning "3: this 'for' clause" } */ foo (2); /* { dg-message "5: ...this statement" } */ FOR_EACH (i, 0, 10); /* { dg-message "3: in expansion of macro .FOR_EACH." } */ foo (2); /* { dg-message "5: ...this statement" } */ FOR_EACH (i, 0, 10); /* { dg-message "3: in expansion of macro .FOR_EACH." } */ { /* { dg-message "5: ...this statement" } */ foo (3); } FOR_EACH (i, 0, 10); /* { dg-message "3: in expansion of macro .FOR_EACH." } */ { /* { dg-message "3: ...this statement" } */ foo (3); } while (i++); { /* { dg-warning "3: this 'while' clause" } */ foo (3); } if (i++); { /* { dg-warning "3: this 'if' clause" } */ foo (3); } if (flagA) { foo (1); } else /* { dg-warning "5: this 'else' clause" } */ if (flagB) foo (2); foo (3); /* { dg-message "5: ...this statement" } */ if (flagA) foo (1); else if (flagB); /* { dg-warning "8: this 'if' clause" } */ foo (2); /* { dg-message "5: ...this statement" } */ for (i = 0; /* { dg-warning "3: this 'for' clause" } */ i < 10; i++); foo (i); /* { dg-message "5: ...this statement" } */ if (flagA) { foo (1); } else if (flagB); /* { dg-warning "8: this 'if' clause" } */ { /* { dg-message "3: ...this statement" } */ foo (2); } #undef EMPTY #undef FOR_EACH } /* The following function contains code whose indentation is not great but not misleading, thus we don't warn. */ void fn_38 (void) { int i = 0; while (flagA) ; foo (0); if (flagB) ; { foo (0); } while (flagC); foo (2); if (flagA) while (flagC++); else foo (2); if (i) while (i++ < 10000); foo (5); if (i) while (i++ < 10000); foo (5); if (flagA) { foo (1); } else if (flagB) foo (2); foo (3); if (flagA) { foo (1); } else if (flagB) foo (2); foo (3); for (i = 0; i < 10; i++ ); foo (i); } /* The following function contains good indentation which we definitely should not warn about. */ void fn_39 (void) { int i; if (flagA) ; if (flagB) ; if (flagA) if (flagB) foo (0); else foo (1); else foo (2); for (i = 0; i < 10; i++); foo (i); do foo (0); while (flagA); } /* We shouldn't complain about the following function. */ #define emit void pr69122 (void) { if (flagA) foo (0); emit foo (1); } #undef emit /* In the following, the 'if' within the 'for' statement is not indented, but arguably should be. The for loop: "for (cnt = 0; cnt < thousands_len; ++cnt)" does not guard this conditional: "cnt < thousands_len;". and the poor indentation is not misleading. Verify that we do not erroneously emit a warning about this. Based on an example seen in glibc (PR c/68187). */ void fn_40_a (const char *end, const char *thousands, int thousands_len) { int cnt; while (flagA) if (flagA && ({ for (cnt = 0; cnt < thousands_len; ++cnt) if (thousands[cnt] != end[cnt]) break; cnt < thousands_len; }) && flagB) break; } /* As above, but with the indentation within the "for" loop fixed. We should not emit a warning for this, either. */ void fn_40_b (const char *end, const char *thousands, int thousands_len) { int cnt; while (flagA) if (flagA && ({ for (cnt = 0; cnt < thousands_len; ++cnt) if (thousands[cnt] != end[cnt]) break; cnt < thousands_len; }) && flagB) break; } /* We should not warn for the following (based on libstdc++-v3/src/c++11/random.cc:random_device::_M_init). */ void fn_41_a (void) { if (flagA) { } else if (flagB) fail: foo (0); foo (1); if (!flagC) goto fail; } /* Tweaked version of the above (with the label indented), which we should also not warn for. */ void fn_41_b (void) { if (flagA) { } else if (flagB) fail: foo (0); foo (1); if (!flagC) goto fail; } /* In the following, the "if (i > 0)" is poorly indented, and ought to be on the same column as "engine_ref_debug(e, 0, -1)" However, it is not misleadingly indented, due to the presence of that macro. Verify that we do not emit a warning about it not being guarded by the "else" clause above. Based on an example seen in OpenSSL 1.0.1, which was filed as PR c/68187 in comment #1, though it's arguably a separate bug to the one in comment #0. */ int fn_42_a (int locked) { #define engine_ref_debug(X, Y, Z) int i; if (locked) i = foo (0); else i = foo (1); engine_ref_debug(e, 0, -1) if (i > 0) return 1; return 0; #undef engine_ref_debug } /* As above, but the empty macro is at the same indentation level. This *is* misleading; verify that we do emit a warning about it. */ int fn_42_b (int locked) { #define engine_ref_debug(X, Y, Z) int i; if (locked) i = foo (0); else /* { dg-warning "this .else. clause" } */ i = foo (1); engine_ref_debug(e, 0, -1) if (i > 0) /* { dg-message "...this statement" } */ return 1; return 0; #undef engine_ref_debug } /* As above, but where the body is a semicolon "hidden" by a preceding comment, where the semicolon is not in the same column as the successor "if" statement, but the empty macro expansion is at the same indentation level as the guard. This is poor indentation, but not misleading; verify that we don't emit a warning about it. */ int fn_42_c (int locked, int i) { #define engine_ref_debug(X, Y, Z) if (locked) /* blah */; engine_ref_debug(e, 0, -1) if (i > 0) return 1; return 0; #undef engine_ref_debug } /* We shouldn't complain about the following function. */ #define ENABLE_FEATURE int pr70085 (int x, int y) { if (x > y) return x - y; #ifdef ENABLE_FEATURE if (x == y) return 0; #endif return -1; } #undef ENABLE_FEATURE /* Additional test coverage for PR c/68187, with various locations for a pair of aligned statements ("foo (2);" and "foo (3);") that may or may not be misleadingly indented. */ /* Before the "}". The two statements aren't visually "within" the above line, so we shouldn't warn. */ void test43_a (void) { if (flagA) { foo (1); } else if (flagB) foo (2); foo (3); } /* Aligned with the "}". Again, the two statements aren't visually "within" the above line, so we shouldn't warn. */ void test43_b (void) { if (flagA) { foo (1); } else if (flagB) foo (2); foo (3); } /* Indented between the "}" and the "else". The two statements are indented "within" the line above, so appear that they would be guarded together. We should warn about this. */ void test43_c (void) { if (flagA) { foo (1); } else if (flagB) /* { dg-message "...this .if. clause" } */ foo (2); foo (3); /* { dg-message "...this statement" } */ } /* Aligned with the "else". Likewise, we should warn. */ void test43_d (void) { if (flagA) { foo (1); } else if (flagB) /* { dg-message "...this .if. clause" } */ foo (2); foo (3); /* { dg-message "...this statement" } */ } /* Indented between the "else" and the "if". Likewise, we should warn. */ void test43_e (void) { if (flagA) { foo (1); } else if (flagB) /* { dg-message "...this .if. clause" } */ foo (2); foo (3); /* { dg-message "...this statement" } */ } /* Aligned with the "if". Likewise, we should warn. */ void test43_f (void) { if (flagA) { foo (1); } else if (flagB) /* { dg-warning "this .else. clause" } */ foo (2); foo (3); /* { dg-message "...this statement" } */ } /* Indented more than the "if". Likewise, we should warn. */ void test43_g (void) { if (flagA) { foo (1); } else if (flagB) /* { dg-message "...this .if. clause" } */ foo (2); foo (3); /* { dg-message "...this statement" } */ } /* Again, but without the 2nd "if". */ /* Before the "}". As before, the two statements aren't visually "within" the above line, so we shouldn't warn. */ void test44_a (void) { if (flagA) { foo (1); } else foo (2); foo (3); } /* Aligned with the "}". As before, the two statements aren't visually "within" the above line, so we shouldn't warn. */ void test44_b (void) { if (flagA) { foo (1); } else foo (2); foo (3); } /* Indented between the "}" and the "else". The two statements are indented "within" the line above, so appear that they would be guarded together. We should warn about this. */ void test44_c (void) { if (flagA) { foo (1); } else /* { dg-warning "this .else. clause" } */ foo (2); foo (3); /* { dg-message "...this statement" } */ } /* Aligned with the "else". Likewise, we should warn. */ void test44_d (void) { if (flagA) { foo (1); } else /* { dg-warning "this .else. clause" } */ foo (2); foo (3); /* { dg-message "...this statement" } */ } /* Indented more than the "else". Likewise, we should warn. */ void test44_e (void) { if (flagA) { foo (1); } else /* { dg-warning "this .else. clause" } */ foo (2); foo (3); /* { dg-message "...this statement" } */ }