public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: David Malcolm <dmalcolm@redhat.com>
To: Patrick Palka <patrick@parcs.ath.cx>
Cc: GCC Patches <gcc-patches@gcc.gnu.org>
Subject: Re: [PATCH 1/2] PR c/68187: fix overzealous -Wmisleading-indentation (comment #0)
Date: Thu, 03 Mar 2016 15:56:00 -0000	[thread overview]
Message-ID: <1457020600.1637.29.camel@redhat.com> (raw)
In-Reply-To: <CA+C-WL_0-h4ZOF0n+jx+qg=c=-RVMUAy6aGaHeMkGrs4Ku7aWw@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 4844 bytes --]

On Thu, 2016-03-03 at 10:24 -0500, Patrick Palka wrote:
> On Thu, Mar 3, 2016 at 10:21 AM, David Malcolm <dmalcolm@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);

No, because the rejection based on indentation is done relative to
 guard_line_first_nws, rather than guard_vis_column (I tried doing it
via the latter in one version of the patch, and that broke some of the
existing cases, so I didn't make that change).

See the attached test file (which doesn't have dg-directives yet); the
example you give is test1_d, with an open-brace added to the "if (p)".

Trunk emits warnings for:
  * test1_c
  * test1_d
  * test1_e
  * test1_f (two warnings, one for the "if", one for the "else")
  * test1_g
  * test2_c
  * test2_d
  * test2_e

With the patches, it emits warnings for:
  * test1_c
  * test1_d
  * test1_e
  * test1_f (just one warnings, for the "if")
  * test1_g
  * test2_c
  * test2_d
  * test2_e

so the only change is the removal of the erroneous double warning for
the "else" in test1_f.

I can add dg-directives and add the attachment to Wmisleading
-indentation.c as part of the patch (or keep it as a separate new test
file, the former is getting large).

[-- Attachment #2: Wmisleading-indentation-4.c --]
[-- Type: text/x-csrc, Size: 1830 bytes --]

/* PR c/68187.  */
/* { dg-options "-Wmisleading-indentation" } */
/* { dg-do compile } */

extern int foo (int);
extern int bar (int, int);
extern int flagA;
extern int flagB;
extern int flagC;
extern int flagD;

/* Before the "}".  */

void
test1_a (void)
{
  if (flagA) {
    foo (1);
  } else if (flagB)
 foo (2);
 foo (3);
}

/* Aligned with the "}".  */

void
test1_b (void)
{
  if (flagA) {
    foo (1);
  } else if (flagB)
  foo (2);
  foo (3);
}

/* Indented between the "}" and the "else".  */

void
test1_c (void)
{
  if (flagA) {
    foo (1);
  } else if (flagB)
   foo (2);
   foo (3);
}

/* Aligned with the "else".  */

void
test1_d (void)
{
  if (flagA) {
    foo (1);
  } else if (flagB)
    foo (2);
    foo (3);
}

/* Indented between the "else" and the "if".  */

void
test1_e (void)
{
  if (flagA) {
    foo (1);
  } else if (flagB)
      foo (2);
      foo (3);
}

/* Aligned with the "if".  */

void
test1_f (void)
{
  if (flagA) {
    foo (1);
  } else if (flagB)
         foo (2);
         foo (3);
}

/* Indented more than the "if".  */

void
test1_g (void)
{
  if (flagA) {
    foo (1);
  } else if (flagB)
            foo (2);
            foo (3);
}

/* Again, but without the 2nd "if".  */

/* Before the "}".  */

void
test2_a (void)
{
  if (flagA) {
    foo (1);
  } else
 foo (2);
 foo (3);
}

/* Aligned with the "}".  */

void
test2_b (void)
{
  if (flagA) {
    foo (1);
  } else
  foo (2);
  foo (3);
}

/* Indented between the "}" and the "else".  */

void
test2_c (void)
{
  if (flagA) {
    foo (1);
  } else
   foo (2);
   foo (3);
}

/* Aligned with the "else".  */

void
test2_d (void)
{
  if (flagA) {
    foo (1);
  } else
    foo (2);
    foo (3);
}

/* Indented more than the "else".  */

void
test2_e (void)
{
  if (flagA) {
    foo (1);
  } else
        foo (2);
        foo (3);
}

  reply	other threads:[~2016-03-03 15:56 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-03 14:58 David Malcolm
2016-03-03 14:58 ` [PATCH 2/2] PR c/68187: fix overzealous -Wmisleading-indentation (comment #1) David Malcolm
2016-03-03 17:16   ` Patrick Palka
2016-03-04 12:53     ` Bernd Schmidt
2016-03-04 13:05       ` Marek Polacek
2016-03-04  7:20   ` Jeff Law
2016-03-03 15:25 ` [PATCH 1/2] PR c/68187: fix overzealous -Wmisleading-indentation (comment #0) Patrick Palka
2016-03-03 15:56   ` David Malcolm [this message]
2016-03-03 16:58     ` Patrick Palka
2016-03-11 20:05     ` [committed 1/2] Wmisleading-indentation: add reproducer for PR c/70085 David Malcolm
2016-03-11 20:05       ` [committed 2/2] Wmisleading-indentation.c: add more test cases for PR c/68187 David Malcolm
2016-03-04  7:15 ` [PATCH 1/2] PR c/68187: fix overzealous -Wmisleading-indentation (comment #0) Jeff Law

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1457020600.1637.29.camel@redhat.com \
    --to=dmalcolm@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=patrick@parcs.ath.cx \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).