c-lex.c (c_lex_with_flags): For CPP_COMMENT token with PREV_FALLTHROUGH...
authorJakub Jelinek <jakub@redhat.com>
Sat, 8 Oct 2016 10:48:54 +0000 (12:48 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Sat, 8 Oct 2016 10:48:54 +0000 (12:48 +0200)
* c-lex.c (c_lex_with_flags) <case CPP_COMMENT>: For CPP_COMMENT
token with PREV_FALLTHROUGH, skip all following CPP_PADDING and
CPP_COMMENT tokens and set add_flags to PREV_FALLTHROUGH afterwards.

* doc/invoke.texi (-Wimplicit-fallthrough): Document the accepted
FALLTHRU comment styles.

* lex.c (fallthrough_comment_p): Fix off-by-one size comparison
errors, cleanup.
(_cpp_lex_direct): Allow arbitrary comments in between
fallthrough_comment_p comment and following token.

* c-c++-common/Wimplicit-fallthrough-23.c: New test.
* c-c++-common/Wimplicit-fallthrough-24.c: New test.

From-SVN: r240884

gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-lex.c
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/Wimplicit-fallthrough-23.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/Wimplicit-fallthrough-24.c [new file with mode: 0644]
libcpp/ChangeLog
libcpp/lex.c

index a7d6689566db5d56740e1aba20a3b8d2fa5d985d..353fdba709cd4cc12756e594d82afb05dc91eb8b 100644 (file)
@@ -1,3 +1,8 @@
+2016-10-08  Jakub Jelinek  <jakub@redhat.com>
+
+       * doc/invoke.texi (-Wimplicit-fallthrough): Document the accepted
+       FALLTHRU comment styles.
+
 2016-10-07  Andrew Pinski  <apinski@cavium.com>
 
        * config/aarch64/aarch64-arches.def (AARCH64_ARCH): #undef at the end.
index 52ba9b8fdebba22497185c67997abd53d073386d..9f6b16d7306cac4b1ebc259593e6ee98803a2b10 100644 (file)
@@ -1,3 +1,9 @@
+2016-10-08  Jakub Jelinek  <jakub@redhat.com>
+
+       * c-lex.c (c_lex_with_flags) <case CPP_COMMENT>: For CPP_COMMENT
+       token with PREV_FALLTHROUGH, skip all following CPP_PADDING and
+       CPP_COMMENT tokens and set add_flags to PREV_FALLTHROUGH afterwards.
+
 2016-10-07  Jakub Jelinek  <jakub@redhat.com>
 
        Implement LWG2296 helper intrinsic
index 5c6496ebecf83784db4e4c2c3626d2777142a8e3..e3803b0186cd5d42fd2701a572bad9bb1c08d3ae 100644 (file)
@@ -596,9 +596,21 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
     case CPP_MACRO_ARG:
       gcc_unreachable ();
 
-    /* CPP_COMMENT will appear when compiling with -C and should be
-       ignored.  */
-     case CPP_COMMENT:
+    /* CPP_COMMENT will appear when compiling with -C.  Ignore, except
+       when it is a FALLTHROUGH comment, in that case set
+       PREV_FALLTHROUGH flag on the next non-comment token.  */
+    case CPP_COMMENT:
+      if (tok->flags & PREV_FALLTHROUGH)
+       {
+         do
+           {
+             tok = cpp_get_token_with_location (parse_in, loc);
+             type = tok->type;
+           }
+         while (type == CPP_PADDING || type == CPP_COMMENT);
+         add_flags |= PREV_FALLTHROUGH;
+         goto retry_after_at;
+       }
        goto retry;
 
     default:
index 22af6e4567381bbcc528fae66779233d64dc7b55..e1a3e5f291faebd42e08387d108b942f3d40ac75 100644 (file)
@@ -4170,10 +4170,26 @@ C++17 provides a standard way to suppress the @option{-Wimplicit-fallthrough}
 warning using @code{[[fallthrough]];} instead of the GNU attribute.  In C++11
 or C++14 users can use @code{[[gnu::fallthrough]];}, which is a GNU extension.
 Instead of the these attributes, it is also possible to add a "falls through"
-comment to silence the warning.  GCC accepts a wide range of such comments,
-for example all of "Falls through.", "fallthru", "FALLS-THROUGH" work.  This
-comment needs to consist of two words merely, optionally followed by periods
-or whitespaces.
+comment to silence the warning.  The whole body of the C or C++ style comment
+should match one of the following regular expressions:
+
+@itemize @bullet
+
+@item @code{-fallthrough}
+
+@item @code{@@fallthrough@@}
+
+@item @code{[ \t]*FALL(S | |-)?THR(OUGH|U)\.?[ \t]*}
+
+@item @code{[ \t]*Fall((s | |-)[Tt]|t)hr(ough|u)\.?[ \t]*}
+
+@item @code{[ \t]*fall(s | |-)?thr(ough|u)\.?[ \t]*}
+
+@end itemize
+
+and the comment needs to be followed after optional whitespace and other comments
+by @code{case} or @code{default} keywords or by a user label that preceeds some
+@code{case} or @code{default} label.
 
 @smallexample
 @group
index 2214179cbd4bb4be5dd52e22413f0e42e8d3b2d8..1868c4cca8f6291b19daae38111ec19f0abeed6b 100644 (file)
@@ -1,3 +1,8 @@
+2016-10-08  Jakub Jelinek  <jakub@redhat.com>
+
+       * c-c++-common/Wimplicit-fallthrough-23.c: New test.
+       * c-c++-common/Wimplicit-fallthrough-24.c: New test.
+
 2016-10-07  Fritz Reese  <fritzoreese@gmail.com>
 
        * gfortran.dg/dec_union_11.f90: New testcase.
diff --git a/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-23.c b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-23.c
new file mode 100644 (file)
index 0000000..137b517
--- /dev/null
@@ -0,0 +1,123 @@
+/* { dg-do compile } */
+/* { dg-options "-Wimplicit-fallthrough" } */
+
+void bar (int);
+
+void
+foo (int i)
+{
+  switch (i)
+    {
+    case 1:
+      bar (1);                 /* { dg-bogus "this statement may \[laf]* through" } */
+      /* FALLTHROUGH */
+    case 2:
+      bar (2);
+      break;
+    case 3:
+      bar (3);                 /* { dg-bogus "this statement may \[laf]* through" } */
+      /* FALLS THRU.  */
+      /* Some other comment.  */
+    case 4:
+      bar (4);
+      break;
+    case 7:
+      bar (7);                 /* { dg-bogus "this statement may \[laf]* through" } */
+      /* Some comment.  */
+      /* fallthrough.  */
+      /* Some other comment.  */
+      /* And yet another.  */
+    case 8:
+      bar (8);
+      break;
+    case 15:
+      bar (15);                        /* { dg-bogus "this statement may \[laf]* through" } */
+      /*-fallthrough*/
+    case 16:
+      bar (16);
+      break;
+    case 17:
+      bar (17);                        /* { dg-bogus "this statement may \[laf]* through" } */
+      /*@fallthrough@*/
+    case 18:
+      bar (18);
+      break;
+    case 23:
+      bar (23);                        /* { dg-bogus "this statement may \[laf]* through" } */
+      /*fallthru*/
+    case 24:
+      bar (24);
+      break;
+    case 31:
+      bar (31);                        /* { dg-bogus "this statement may \[laf]* through" } */
+      /*Falls thru*/
+    case 32:
+      bar (32);
+      break;
+    case 33:
+      bar (33);                        /* { dg-bogus "this statement may \[laf]* through" } */
+      /*Fall-through*/
+    case 34:
+      bar (34);
+      break;
+    default:
+      break;
+    }
+  switch (i)
+    {
+    case 1:
+      bar (1);                 /* { dg-bogus "this statement may \[laf]* through" } */
+      // FALLTHROUGH
+    case 2:
+      bar (2);
+      break;
+    case 3:
+      bar (3);                 /* { dg-bogus "this statement may \[laf]* through" } */
+      // FALLS THRU.  
+      // Some other comment.
+    case 4:
+      bar (4);
+      break;
+    case 7:
+      bar (7);                 /* { dg-bogus "this statement may \[laf]* through" } */
+      // Some comment.
+      // fallthrough
+      // Some other comment.
+      // And yet another.
+    case 8:
+      bar (8);
+      break;
+    case 15:
+      bar (15);                        /* { dg-bogus "this statement may \[laf]* through" } */
+      //-fallthrough
+    case 16:
+      bar (16);
+      break;
+    case 17:
+      bar (17);                        /* { dg-bogus "this statement may \[laf]* through" } */
+      //@fallthrough@
+    case 18:
+      bar (18);
+      break;
+    case 23:
+      bar (23);                        /* { dg-bogus "this statement may \[laf]* through" } */
+      //fallthru
+    case 24:
+      bar (24);
+      break;
+    case 31:
+      bar (31);                        /* { dg-bogus "this statement may \[laf]* through" } */
+      //Falls thru
+    case 32:
+      bar (32);
+      break;
+    case 33:
+      bar (33);                        /* { dg-bogus "this statement may \[laf]* through" } */
+      //Fall-through
+    case 34:
+      bar (34);
+      break;
+    default:
+      break;
+    }
+}
diff --git a/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-24.c b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-24.c
new file mode 100644 (file)
index 0000000..15f33c6
--- /dev/null
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+/* { dg-options "-Wimplicit-fallthrough -C" } */
+
+#include "Wimplicit-fallthrough-23.c"
index 96b9047501bfe8c98dafd73a0f74f6942470a3a9..faecb162caf173ce7fdb4b91f1ff5e568059a03e 100644 (file)
@@ -1,3 +1,10 @@
+2016-10-08  Jakub Jelinek  <jakub@redhat.com>
+
+       * lex.c (fallthrough_comment_p): Fix off-by-one size comparison
+       errors, cleanup.
+       (_cpp_lex_direct): Allow arbitrary comments in between
+       fallthrough_comment_p comment and following token.
+
 2016-10-04  Kelvin Nilsen  <kelvin@gcc.gnu.org>
 
        PR target/77847
index 6d2e596e2d407948d1af8a5b7e4f23d79a4a2bcd..d960aa869e4c7277ae1f78b280cb49e6af4e0e18 100644 (file)
@@ -2061,7 +2061,7 @@ fallthrough_comment_p (cpp_reader *pfile, const unsigned char *comment_start)
     }
   /* Whole comment contents (regex):
      [ \t]*FALL(S | |-)?THR(OUGH|U)\.?[ \t]*
-     [ \t]*Fall(s | |-)?[Tt]hr(ough|u)\.?[ \t]*
+     [ \t]*Fall((s | |-)[Tt]|t)hr(ough|u)\.?[ \t]*
      [ \t]*fall(s | |-)?thr(ough|u)\.?[ \t]*
    */
   else
@@ -2071,30 +2071,27 @@ fallthrough_comment_p (cpp_reader *pfile, const unsigned char *comment_start)
       unsigned char f = *from;
       if (f != 'F' && f != 'f')
        return false;
-      if ((size_t) (pfile->buffer->cur - from) < sizeof "fallthrough")
+      if ((size_t) (pfile->buffer->cur - from) < sizeof "fallthru" - 1)
        return false;
       bool all_upper = false;
       if (f == 'F' && memcmp (from + 1, "ALL", sizeof "ALL" - 1) == 0)
        all_upper = true;
       else if (memcmp (from + 1, "all", sizeof "all" - 1))
        return false;
-      if (from[sizeof "fall" - 1] == (all_upper ? 'S' : 's')
-         && from[sizeof "falls" - 1] == ' ')
-       from += sizeof "falls " - 1;
-      else if (from[sizeof "fall" - 1] == ' '
-              || from[sizeof "fall" - 1] == '-')
-       from += sizeof "fall " - 1;
-      else if (from[sizeof "fall" - 1] != (all_upper ? 'T' : 't'))
+      from += sizeof "fall" - 1;
+      if (*from == (all_upper ? 'S' : 's') && from[1] == ' ')
+       from += 2;
+      else if (*from == ' ' || *from == '-')
+       from++;
+      else if (*from != (all_upper ? 'T' : 't'))
        return false;
-      else
-       from += sizeof "fall" - 1;
       if ((f == 'f' || *from != 'T') && (all_upper || *from != 't'))
        return false;
-      if ((size_t) (pfile->buffer->cur - from) < sizeof "thru")
+      if ((size_t) (pfile->buffer->cur - from) < sizeof "thru" - 1)
        return false;
       if (memcmp (from + 1, all_upper ? "HRU" : "hru", sizeof "hru" - 1))
        {
-         if ((size_t) (pfile->buffer->cur - from) < sizeof "through")
+         if ((size_t) (pfile->buffer->cur - from) < sizeof "through" - 1)
            return false;
          if (memcmp (from + 1, all_upper ? "HROUGH" : "hrough",
                      sizeof "hrough" - 1))
@@ -2399,7 +2396,8 @@ _cpp_lex_direct (cpp_reader *pfile)
 {
   cppchar_t c;
   cpp_buffer *buffer;
-  const unsigned char *comment_start = NULL;
+  const unsigned char *comment_start;
+  bool fallthrough_comment = false;
   cpp_token *result = pfile->cur_token++;
 
  fresh_line:
@@ -2427,7 +2425,7 @@ _cpp_lex_direct (cpp_reader *pfile)
          return result;
        }
       if (buffer != pfile->buffer)
-       comment_start = NULL;
+       fallthrough_comment = false;
       if (!pfile->keep_tokens)
        {
          pfile->cur_run = &pfile->base_run;
@@ -2536,8 +2534,7 @@ _cpp_lex_direct (cpp_reader *pfile)
        }
 
       /* Signal FALLTHROUGH comment followed by another token.  */
-      if (comment_start
-         && fallthrough_comment_p (pfile, comment_start))
+      if (fallthrough_comment)
        result->flags |= PREV_FALLTHROUGH;
       break;
 
@@ -2624,13 +2621,16 @@ _cpp_lex_direct (cpp_reader *pfile)
          break;
        }
 
+      if (fallthrough_comment_p (pfile, comment_start))
+       fallthrough_comment = true;
+
       if (!pfile->state.save_comments)
        {
          result->flags |= PREV_WHITE;
          goto update_tokens_line;
        }
 
-      if (fallthrough_comment_p (pfile, comment_start))
+      if (fallthrough_comment)
        result->flags |= PREV_FALLTHROUGH;
 
       /* Save the comment as a token in its own right.  */