From patchwork Fri Sep 30 20:05:57 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 677215 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3sm2Wb41BNz9s5w for ; Sat, 1 Oct 2016 06:06:19 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=CFy76ywX; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:reply-to:references:mime-version :content-type:in-reply-to; q=dns; s=default; b=FqxWIkjvxp64bojts DVPO0x+xUYS1miR9eMqjyiVRqCZFDw5s9nXvnxuiwgb8jocH2KBHwqtCO5WEMmDL Kjp6jJW/pLGTCYJ9FlW9etLtIgrDbW5vQbTknsYvhE34M73I8gdHoBRP+IBoPJa+ GBF8HBCsixm+Y2p7aBOrs2qX08= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:reply-to:references:mime-version :content-type:in-reply-to; s=default; bh=urzQNflWF03wqzW4RyT4alK yDKU=; b=CFy76ywXcWNnILzxay2M9loOoY1QjcyOzQdt6+OvocGRv+kC5UBEhaT fTjn15uqo0IHB10WuewTnL3n58J763qfe+VaTXstl+ch3q3BoB6CRIepmnnIvFpZ QWJ3w6Dj/sXbCjncJwKt3pWFjJAFM/+eyc5zFlgU77MeMfFLlJgE= Received: (qmail 79197 invoked by alias); 30 Sep 2016 20:06:10 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 79183 invoked by uid 89); 30 Sep 2016 20:06:09 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-4.9 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=2256, 2115, 1123, t X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 30 Sep 2016 20:06:06 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 758A4624DD; Fri, 30 Sep 2016 20:06:05 +0000 (UTC) Received: from tucnak.zalov.cz (ovpn-116-44.ams2.redhat.com [10.36.116.44]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u8UK621X007134 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Fri, 30 Sep 2016 16:06:03 -0400 Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.15.2/8.15.2) with ESMTP id u8UK5x9O016029; Fri, 30 Sep 2016 22:06:00 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.15.2/8.15.2/Submit) id u8UK5vvd016028; Fri, 30 Sep 2016 22:05:57 +0200 Date: Fri, 30 Sep 2016 22:05:57 +0200 From: Jakub Jelinek To: Marek Polacek Cc: Jason Merrill , "Joseph S. Myers" , gcc-patches@gcc.gnu.org Subject: Re: [PATCH] Fix -Wimplicit-fallthrough -C, handle some more comment styles and comments in between FALLTHRU comment and label Message-ID: <20160930200557.GG7282@tucnak.redhat.com> Reply-To: Jakub Jelinek References: <20160929201633.GV7282@tucnak.redhat.com> <20160930092627.GZ3223@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20160930092627.GZ3223@redhat.com> User-Agent: Mutt/1.5.24 (2015-08-30) X-IsSubscribed: yes On Fri, Sep 30, 2016 at 11:26:27AM +0200, Marek Polacek wrote: > I haven't gone over the patch in detail yet, but I wonder if we should > also accept /* Else, fall through. */ (to be found e.g. in aarch64-simd.md). Here is the patch split into a series of 3 patches (the later patches depend on the earlier ones): 1) the first patch fixes some bugs and fixes also -Wimplicit-fallthrough -C 2) the second patch adds the else and intentional/ly etc. 3) the third one adds the optional comma between else and fall Bootstrapped/regtested on x86_64-linux and i686-linux, ok? Jakub 2016-09-30 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. * 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-22.c: New test. * c-c++-common/Wimplicit-fallthrough-23.c: New test. 2016-09-30 Jakub Jelinek * doc/invoke.texi (-Wimplicit-fallthrough): Document FALLTHRU comment style changes. * lex.c (fallthrough_comment_p): Extend to handle more common FALLTHRU comment styles. * c-c++-common/Wimplicit-fallthrough-22.c (foo): Add further tests. --- gcc/doc/invoke.texi.jj 2016-09-30 17:21:11.743575991 +0200 +++ gcc/doc/invoke.texi 2016-09-30 17:39:41.838766235 +0200 @@ -4166,11 +4166,13 @@ should match one of the following regula @item @code{@@fallthrough@@} -@item @code{[ \t]*FALL(S | |-)?THR(OUGH|U)\.?[ \t]*} +@item @code{lint -fallthrough ?} -@item @code{[ \t]*Fall((s | |-)[Tt]|t)hr(ough|u)\.?[ \t]*} +@item @code{[ \t.!]*(ELSE |INTENTIONAL(LY)? )?FALL(S | |-)?THR(OUGH|U)[ \t.!]*(-[^\n\r]*)?} -@item @code{[ \t]*fall(s | |-)?thr(ough|u)\.?[ \t]*} +@item @code{[ \t.!]*(Else |Intentional(ly)? )?Fall((s | |-)[Tt]|t)hr(ough|u)[ \t.!]*(-[^\n\r]*)?} + +@item @code{[ \t.!]*([Ee]lse |[Ii]ntentional(ly)? )?fall(s | |-)?thr(ough|u)[ \t.!]*(-[^\n\r]*)?} @end itemize --- libcpp/lex.c.jj 2016-09-30 17:20:46.959884436 +0200 +++ libcpp/lex.c 2016-09-30 17:39:38.854803331 +0200 @@ -2059,22 +2059,86 @@ fallthrough_comment_p (cpp_reader *pfile from += 1 + len; } /* Whole comment contents (regex): - [ \t]*FALL(S | |-)?THR(OUGH|U)\.?[ \t]* - [ \t]*Fall((s | |-)[Tt]|t)hr(ough|u)\.?[ \t]* - [ \t]*fall(s | |-)?thr(ough|u)\.?[ \t]* + lint -fallthrough ? + */ + else if (*from == 'l') + { + size_t len = sizeof "int -fallthrough" - 1; + if ((size_t) (pfile->buffer->cur - from - 1) < len) + return false; + if (memcmp (from + 1, "int -fallthrough", len)) + return false; + from += 1 + len; + if (*from == ' ') + from++; + } + /* Whole comment contents (regex): + [ \t.!]*(ELSE |INTENTIONAL(LY)? )?FALL(S | |-)?THR(OUGH|U)[ \t.!]*(-[^\n\r]*)? + [ \t.!]*(Else |Intentional(ly)? )?Fall((s | |-)[Tt]|t)hr(ough|u)[ \t.!]*(-[^\n\r]*)? + [ \t.!]*([Ee]lse |[Ii]ntentional(ly)? )?fall(s | |-)?thr(ough|u)[ \t.!]*(-[^\n\r]*)? */ else { - while (*from == ' ' || *from == '\t') + while (*from == ' ' || *from == '\t' || *from == '.' || *from == '!') from++; unsigned char f = *from; + bool all_upper = false; + if (f == 'E' || f == 'e') + { + if ((size_t) (pfile->buffer->cur - from) + < sizeof "else fallthru" - 1) + return false; + if (f == 'E' && memcmp (from + 1, "LSE F", sizeof "LSE F" - 1) == 0) + all_upper = true; + else if (memcmp (from + 1, "lse ", sizeof "lse " - 1)) + return false; + from += sizeof "else " - 1; + if (f == 'e' && *from == 'F') + return false; + f = *from; + } + else if (f == 'I' || f == 'i') + { + if ((size_t) (pfile->buffer->cur - from) + < sizeof "intentional fallthru" - 1) + return false; + if (f == 'I' && memcmp (from + 1, "NTENTIONAL", + sizeof "NTENTIONAL" - 1) == 0) + all_upper = true; + else if (memcmp (from + 1, "ntentional", + sizeof "ntentional" - 1)) + return false; + from += sizeof "intentional" - 1; + if (*from == ' ') + { + from++; + if (all_upper && *from == 'f') + return false; + } + else if (all_upper) + { + if (memcmp (from, "LY F", sizeof "LY F" - 1)) + return false; + from += sizeof "LY " - 1; + } + else + { + if (memcmp (from, "ly ", sizeof "ly " - 1)) + return false; + from += sizeof "ly " - 1; + } + if (f == 'i' && *from == 'F') + return false; + f = *from; + } if (f != 'F' && f != 'f') return false; 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 (all_upper) + return false; else if (memcmp (from + 1, "all", sizeof "all" - 1)) return false; from += sizeof "fall" - 1; @@ -2099,10 +2163,28 @@ fallthrough_comment_p (cpp_reader *pfile } else from += sizeof "thru" - 1; - if (*from == '.') - from++; - while (*from == ' ' || *from == '\t') + while (*from == ' ' || *from == '\t' || *from == '.' || *from == '!') from++; + if (*from == '-') + { + from++; + if (*comment_start == '*') + { + do + { + while (*from && *from != '*' + && *from != '\n' && *from != '\r') + from++; + if (*from != '*' || from[1] == '/') + break; + from++; + } + while (1); + } + else + while (*from && *from != '\n' && *from != '\r') + from++; + } } /* C block comment. */ if (*comment_start == '*') --- gcc/testsuite/c-c++-common/Wimplicit-fallthrough-22.c.jj 2016-09-30 17:35:47.908674464 +0200 +++ gcc/testsuite/c-c++-common/Wimplicit-fallthrough-22.c 2016-09-30 17:39:41.833766297 +0200 @@ -21,15 +21,39 @@ foo (int i) case 4: bar (4); break; + case 5: + bar (5); /* { dg-bogus "this statement may \[laf]* through" } */ + /* Else Fall-Thru! */ + case 6: + bar (6); + break; case 7: bar (7); /* { dg-bogus "this statement may \[laf]* through" } */ /* Some comment. */ - /* fallthrough. */ + /* ... fallthrough ... */ /* Some other comment. */ /* And yet another. */ case 8: bar (8); break; + case 9: + bar (9); /* { dg-bogus "this statement may \[laf]* through" } */ + /* Intentional Fallthru */ + case 10: + bar (10); + break; + case 11: + bar (11); /* { dg-bogus "this statement may \[laf]* through" } */ + /* intentionally fall through */ + case 12: + bar (12); + break; + case 13: + bar (13); /* { dg-bogus "this statement may \[laf]* through" } */ + /* Falls Through - for reasons known only to the author. */ + case 14: + bar (14); + break; case 15: bar (15); /* { dg-bogus "this statement may \[laf]* through" } */ /*-fallthrough*/ @@ -42,12 +66,42 @@ foo (int i) case 18: bar (18); break; + case 19: + bar (19); /* { dg-bogus "this statement may \[laf]* through" } */ + /*lint -fallthrough*/ + case 20: + bar (20); + break; + case 21: + bar (21); /* { dg-bogus "this statement may \[laf]* through" } */ + /*lint -fallthrough */ + case 22: + bar (22); + break; case 23: bar (23); /* { dg-bogus "this statement may \[laf]* through" } */ /*fallthru*/ case 24: bar (24); break; + case 25: + bar (25); /* { dg-bogus "this statement may \[laf]* through" } */ + /*Else fallthru*/ + case 26: + bar (26); + break; + case 27: + bar (27); /* { dg-bogus "this statement may \[laf]* through" } */ + /*Intentional fallthru*/ + case 28: + bar (28); + break; + case 29: + bar (29); /* { dg-bogus "this statement may \[laf]* through" } */ + /*Intentionally fallthru*/ + case 30: + bar (30); + break; case 31: bar (31); /* { dg-bogus "this statement may \[laf]* through" } */ /*Falls thru*/ @@ -78,15 +132,39 @@ foo (int i) case 4: bar (4); break; + case 5: + bar (5); /* { dg-bogus "this statement may \[laf]* through" } */ + // Else Fall-Thru! + case 6: + bar (6); + break; case 7: bar (7); /* { dg-bogus "this statement may \[laf]* through" } */ // Some comment. - // fallthrough + // ... fallthrough ... // Some other comment. // And yet another. case 8: bar (8); break; + case 9: + bar (9); /* { dg-bogus "this statement may \[laf]* through" } */ + // Intentional Fallthru + case 10: + bar (10); + break; + case 11: + bar (11); /* { dg-bogus "this statement may \[laf]* through" } */ + // intentionally fall through + case 12: + bar (12); + break; + case 13: + bar (13); /* { dg-bogus "this statement may \[laf]* through" } */ + // Falls Through - for reasons known only to the author. + case 14: + bar (14); + break; case 15: bar (15); /* { dg-bogus "this statement may \[laf]* through" } */ //-fallthrough @@ -99,12 +177,42 @@ foo (int i) case 18: bar (18); break; + case 19: + bar (19); /* { dg-bogus "this statement may \[laf]* through" } */ + //lint -fallthrough + case 20: + bar (20); + break; + case 21: + bar (21); /* { dg-bogus "this statement may \[laf]* through" } */ + //lint -fallthrough + case 22: + bar (22); + break; case 23: bar (23); /* { dg-bogus "this statement may \[laf]* through" } */ //fallthru case 24: bar (24); break; + case 25: + bar (25); /* { dg-bogus "this statement may \[laf]* through" } */ + //Else fallthru + case 26: + bar (26); + break; + case 27: + bar (27); /* { dg-bogus "this statement may \[laf]* through" } */ + //Intentional fallthru + case 28: + bar (28); + break; + case 29: + bar (29); /* { dg-bogus "this statement may \[laf]* through" } */ + //Intentionally fallthru + case 30: + bar (30); + break; case 31: bar (31); /* { dg-bogus "this statement may \[laf]* through" } */ //Falls thru 2016-09-30 Jakub Jelinek * doc/invoke.texi: Document accepting Else, fallthrough. * lex.c (fallthrough_comment_p): Accept Else, fallthrough. * c-c++-common/Wimplicit-fallthrough-22.c (foo): Add further tests. --- gcc/doc/invoke.texi.jj 2016-09-30 17:09:37.170216652 +0200 +++ gcc/doc/invoke.texi 2016-09-30 16:27:10.565840611 +0200 @@ -4168,11 +4168,11 @@ should match one of the following regula @item @code{lint -fallthrough ?} -@item @code{[ \t.!]*(ELSE |INTENTIONAL(LY)? )?FALL(S | |-)?THR(OUGH|U)[ \t.!]*(-[^\n\r]*)?} +@item @code{[ \t.!]*(ELSE,? |INTENTIONAL(LY)? )?FALL(S | |-)?THR(OUGH|U)[ \t.!]*(-[^\n\r]*)?} -@item @code{[ \t.!]*(Else |Intentional(ly)? )?Fall((s | |-)[Tt]|t)hr(ough|u)[ \t.!]*(-[^\n\r]*)?} +@item @code{[ \t.!]*(Else,? |Intentional(ly)? )?Fall((s | |-)[Tt]|t)hr(ough|u)[ \t.!]*(-[^\n\r]*)?} -@item @code{[ \t.!]*([Ee]lse |[Ii]ntentional(ly)? )?fall(s | |-)?thr(ough|u)[ \t.!]*(-[^\n\r]*)?} +@item @code{[ \t.!]*([Ee]lse,? |[Ii]ntentional(ly)? )?fall(s | |-)?thr(ough|u)[ \t.!]*(-[^\n\r]*)?} @end itemize --- libcpp/lex.c.jj 2016-09-30 17:09:37.171216639 +0200 +++ libcpp/lex.c 2016-09-30 16:30:52.048091615 +0200 @@ -2073,9 +2073,9 @@ fallthrough_comment_p (cpp_reader *pfile from++; } /* Whole comment contents (regex): - [ \t.!]*(ELSE |INTENTIONAL(LY)? )?FALL(S | |-)?THR(OUGH|U)[ \t.!]*(-[^\n\r]*)? - [ \t.!]*(Else |Intentional(ly)? )?Fall((s | |-)[Tt]|t)hr(ough|u)[ \t.!]*(-[^\n\r]*)? - [ \t.!]*([Ee]lse |[Ii]ntentional(ly)? )?fall(s | |-)?thr(ough|u)[ \t.!]*(-[^\n\r]*)? + [ \t.!]*(ELSE,? |INTENTIONAL(LY)? )?FALL(S | |-)?THR(OUGH|U)[ \t.!]*(-[^\n\r]*)? + [ \t.!]*(Else,? |Intentional(ly)? )?Fall((s | |-)[Tt]|t)hr(ough|u)[ \t.!]*(-[^\n\r]*)? + [ \t.!]*([Ee]lse,? |[Ii]ntentional(ly)? )?fall(s | |-)?thr(ough|u)[ \t.!]*(-[^\n\r]*)? */ else { @@ -2088,11 +2088,18 @@ fallthrough_comment_p (cpp_reader *pfile if ((size_t) (pfile->buffer->cur - from) < sizeof "else fallthru" - 1) return false; - if (f == 'E' && memcmp (from + 1, "LSE F", sizeof "LSE F" - 1) == 0) + if (f == 'E' && memcmp (from + 1, "LSE", sizeof "LSE" - 1) == 0) all_upper = true; - else if (memcmp (from + 1, "lse ", sizeof "lse " - 1)) + else if (memcmp (from + 1, "lse", sizeof "lse" - 1)) + return false; + from += sizeof "else" - 1; + if (*from == ',') + from++; + if (*from != ' ') + return false; + from++; + if (all_upper && *from == 'f') return false; - from += sizeof "else " - 1; if (f == 'e' && *from == 'F') return false; f = *from; --- gcc/testsuite/c-c++-common/Wimplicit-fallthrough-22.c.jj 2016-09-30 17:09:37.172216627 +0200 +++ gcc/testsuite/c-c++-common/Wimplicit-fallthrough-22.c 2016-09-30 16:32:20.866989186 +0200 @@ -114,6 +114,12 @@ foo (int i) case 34: bar (34); break; + case 35: + bar (35); /* { dg-bogus "this statement may \[laf]* through" } */ + /* Else, fall-through. */ + case 36: + bar (36); + break; default: break; } @@ -225,6 +231,12 @@ foo (int i) case 34: bar (34); break; + case 35: + bar (35); /* { dg-bogus "this statement may \[laf]* through" } */ + // Else, fall-through + case 36: + bar (36); + break; default: break; } --- gcc/c-family/c-lex.c.jj 2016-09-30 18:16:26.303336781 +0200 +++ gcc/c-family/c-lex.c 2016-09-30 18:26:14.650999215 +0200 @@ -598,7 +598,18 @@ c_lex_with_flags (tree *value, location_ /* CPP_COMMENT will appear when compiling with -C and should be ignored. */ - case CPP_COMMENT: + 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: --- gcc/doc/invoke.texi.jj 2016-09-30 18:16:26.308336719 +0200 +++ gcc/doc/invoke.texi 2016-09-30 18:26:33.288766793 +0200 @@ -4157,10 +4157,26 @@ C++17 provides a standard way to suppres 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 --- libcpp/lex.c.jj 2016-09-30 18:16:22.987378137 +0200 +++ libcpp/lex.c 2016-09-30 18:26:33.289766781 +0200 @@ -2060,7 +2060,7 @@ fallthrough_comment_p (cpp_reader *pfile } /* 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 @@ -2070,30 +2070,27 @@ fallthrough_comment_p (cpp_reader *pfile 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)) @@ -2398,7 +2395,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: @@ -2426,7 +2424,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; @@ -2535,8 +2533,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; @@ -2623,13 +2620,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. */ --- gcc/testsuite/c-c++-common/Wimplicit-fallthrough-22.c.jj 2016-09-30 18:16:26.293336906 +0200 +++ gcc/testsuite/c-c++-common/Wimplicit-fallthrough-22.c 2016-09-30 18:26:33.289766781 +0200 @@ -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; + } +} --- gcc/testsuite/c-c++-common/Wimplicit-fallthrough-23.c.jj 2016-09-30 18:16:26.298336844 +0200 +++ gcc/testsuite/c-c++-common/Wimplicit-fallthrough-23.c 2016-09-30 18:26:14.659999103 +0200 @@ -0,0 +1,4 @@ +/* { dg-do compile } */ +/* { dg-options "-Wimplicit-fallthrough -C" } */ + +#include "Wimplicit-fallthrough-22.c"