From 7bad794aa005aa3ee52fc9c872051d8346c09a24 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 8 Oct 2016 12:48:54 +0200 Subject: [PATCH] c-lex.c (c_lex_with_flags): For CPP_COMMENT token with PREV_FALLTHROUGH... * c-lex.c (c_lex_with_flags) : 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 | 5 + gcc/c-family/ChangeLog | 6 + gcc/c-family/c-lex.c | 18 ++- gcc/doc/invoke.texi | 24 +++- gcc/testsuite/ChangeLog | 5 + .../c-c++-common/Wimplicit-fallthrough-23.c | 123 ++++++++++++++++++ .../c-c++-common/Wimplicit-fallthrough-24.c | 4 + libcpp/ChangeLog | 7 + libcpp/lex.c | 36 ++--- 9 files changed, 203 insertions(+), 25 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/Wimplicit-fallthrough-23.c create mode 100644 gcc/testsuite/c-c++-common/Wimplicit-fallthrough-24.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a7d6689566d..353fdba709c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2016-10-08 Jakub Jelinek + + * doc/invoke.texi (-Wimplicit-fallthrough): Document the accepted + FALLTHRU comment styles. + 2016-10-07 Andrew Pinski * config/aarch64/aarch64-arches.def (AARCH64_ARCH): #undef at the end. diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 52ba9b8fdeb..9f6b16d7306 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2016-10-08 Jakub Jelinek + + * c-lex.c (c_lex_with_flags) : 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 Implement LWG2296 helper intrinsic diff --git a/gcc/c-family/c-lex.c b/gcc/c-family/c-lex.c index 5c6496ebecf..e3803b0186c 100644 --- a/gcc/c-family/c-lex.c +++ b/gcc/c-family/c-lex.c @@ -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: diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 22af6e45673..e1a3e5f291f 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2214179cbd4..1868c4cca8f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-10-08 Jakub Jelinek + + * c-c++-common/Wimplicit-fallthrough-23.c: New test. + * c-c++-common/Wimplicit-fallthrough-24.c: New test. + 2016-10-07 Fritz Reese * 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 index 00000000000..137b517c2dd --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-23.c @@ -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 index 00000000000..15f33c670c2 --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-24.c @@ -0,0 +1,4 @@ +/* { dg-do compile } */ +/* { dg-options "-Wimplicit-fallthrough -C" } */ + +#include "Wimplicit-fallthrough-23.c" diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index 96b9047501b..faecb162caf 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,10 @@ +2016-10-08 Jakub Jelinek + + * 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 PR target/77847 diff --git a/libcpp/lex.c b/libcpp/lex.c index 6d2e596e2d4..d960aa869e4 100644 --- a/libcpp/lex.c +++ b/libcpp/lex.c @@ -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. */ -- 2.30.2