On Thu, Mar 3, 2016 at 10:21 AM, David Malcolm <dmalc...@redhat.com> wrote:
> PR c/68187 covers two cases involving poor indentation where
> the indentation is arguably not misleading, but for which
> -Wmisleading-indentation emits a warning.
>
> The two cases appear to be different in nature; one in comment #0
> and the other in comment #1.  Richi marked the bug as a whole as
> a P1 regression; it's not clear to me if he meant one or both of
> these cases, so the following two patches fix both.
>
> The rest of this post addresses the case in comment #0 of the PR;
> the followup post addresses the other case, in comment #1 of the PR.
>
> Building glibc (a9224562cbe9cfb0bd8d9e637a06141141f9e6e3) on x86_64
> led to this diagnostic from -Wmisleading-indentation:
>
> ../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;
>
> Lines 354 and 355 are poorly indented, leading to the warning from
> -Wmisleading-indentation at line 356.
>
> The wording of the warning is clearly wrong: line 356 isn't indented as if
> guarded by line 353, it's more that lines 354 and 355 *aren't* indented.
>
> What's happening is that should_warn_for_misleading_indentation has a
> heuristic for handling "} else", such as:
>
>      if (p)
>        foo (1);
>      } else       // GUARD
>        foo (2);   // BODY
>        foo (3);   // NEXT
>
> and this heuristic uses the first non-whitespace character in the line
> containing GUARD as the column of interest: the "}" character.
>
> In this case we have:
>
>    353        && ({ for (cnt = 0; cnt < thousands_len; ++cnt)  // GUARD
>    354              if (thousands[cnt] != end[cnt])            // BODY
>    355                break;
>    356              cnt < thousands_len; })                    // NEXT
>
> and so it uses the column of the "&&", and treats it as if it were
> indented thus:
>
>    353        for (cnt = 0; cnt < thousands_len; ++cnt)        // GUARD
>    354              if (thousands[cnt] != end[cnt])            // BODY
>    355                break;
>    356              cnt < thousands_len; })                    // NEXT
>
> and thus issues a warning.
>
> As far as I can tell the heuristic in question only makes sense for
> "else" clauses, so the following patch updates it to only use the
> special column when handling "else" clauses, eliminating the
> overzealous warning.

Wouldn't this change have the undesirable effect of no longer warning about:

      if (p)
        foo (1);
      } else if (q)
        foo (2);
        foo (3);

Reply via email to