https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68187
Bug ID: 68187 Summary: Poor error message from -Wmisleading-indentation on glibc's ../stdlib/strtol_l.c Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: dmalcolm at gcc dot gnu.org Target Milestone: --- Building glibc (a9224562cbe9cfb0bd8d9e637a06141141f9e6e3) on x86_64, with gcc r229364 patched to add -Wmisleading-indentation added to -Wall: ../stdlib/strtol_l.c: In function ‘____strtoul_l_internal’: ../stdlib/strtol_l.c:356:9: error: statement is indented as if it were guarded by... [-Werror=misleading-indentation] cnt < thousands_len; }) ^ ../stdlib/strtol_l.c:353:9: note: ...this ‘for’ clause, but it is not && ({ for (cnt = 0; cnt < thousands_len; ++cnt) ^ The code is question looks like this: 348 for (c = *end; c != L_('\0'); c = *++end) 349 if (((STRING_TYPE) c < L_('0') || (STRING_TYPE) c > L_('9')) 350 # ifdef USE_WIDE_CHAR 351 && (wchar_t) c != thousands 352 # else 353 && ({ for (cnt = 0; cnt < thousands_len; ++cnt) 354 if (thousands[cnt] != end[cnt]) 355 break; 356 cnt < thousands_len; }) 357 # endif 358 && (!ISALPHA (c) 359 || (int) (TOUPPER (c) - L_('A') + 10) >= base)) 360 break; It looks like lines 354 and 355 are poorly indented, leading to the warning from -Wmisleading-indentation at line 356. It could be argued that the warning is reasonable here, though I don't like the wording of our warning here: line 356 isn't indented as if guarded by line 353, it's more that lines 354 and 355 *aren't* indented. Specifically: (gdb) call inform (guard_tinfo.location, "guard_tinfo") ../stdlib/strtol_l.c:353:9: note: guard_tinfo && ({ for (cnt = 0; cnt < thousands_len; ++cnt) ^ (gdb) call inform (body_tinfo.location, "body_tinfo") ../stdlib/strtol_l.c:354:9: note: body_tinfo if (thousands[cnt] != end[cnt]) ^ (gdb) call inform (next_tinfo.location, "next_tinfo") ../stdlib/strtol_l.c:356:9: note: next_tinfo cnt < thousands_len; }) ^ (gdb) p guard_exploc $11 = {file = 0x1dd40a0 "../stdlib/strtol_l.c", line = 353, column = 9, data = 0x0, sysp = false} (gdb) p body_exploc $12 = {file = 0x1dd40a0 "../stdlib/strtol_l.c", line = 354, column = 9, data = 0x0, sysp = false} (gdb) p next_stmt_exploc $13 = {file = 0x1dd40a0 "../stdlib/strtol_l.c", line = 356, column = 9, data = 0x0, sysp = false} (gdb) p guard_vis_column $14 = 22 (gdb) p body_vis_column $15 = 22 (gdb) p next_stmt_vis_column $16 = 22 (gdb) p body_type $17 = CPP_KEYWORD I believe it's entering this clause: /* Don't warn if they are aligned on the same column as the guard itself (suggesting autogenerated code that doesn't bother indenting at all). We consider the column of the first but: (gdb) p guard_line_first_nws $18 = 16 (gdb) p body_vis_column $19 = 22 due to the "&& ({ " before the "for" on line 353 and hence it fails the tests, and reaches: /* Otherwise, they are visually aligned: issue a warning. */ return true;