diff options
author | Marek Polacek <polacek@redhat.com> | 2016-09-26 09:42:50 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2016-09-26 09:42:50 +0000 |
commit | 81fea426da8c4687bb32e6894dc26f00ae211822 (patch) | |
tree | 8b84b3de175727d09b7dcf1b5703e0d46b64f9e7 /libcpp | |
parent | 392fa55c799358e198ca85fbea548e60359133c5 (diff) | |
download | gcc-81fea426da8c4687bb32e6894dc26f00ae211822.zip gcc-81fea426da8c4687bb32e6894dc26f00ae211822.tar.gz gcc-81fea426da8c4687bb32e6894dc26f00ae211822.tar.bz2 |
Implement -Wimplicit-fallthrough.
Co-Authored-By: Jakub Jelinek <jakub@redhat.com>
From-SVN: r240485
Diffstat (limited to 'libcpp')
-rw-r--r-- | libcpp/ChangeLog | 10 | ||||
-rw-r--r-- | libcpp/include/cpplib.h | 4 | ||||
-rw-r--r-- | libcpp/lex.c | 100 |
3 files changed, 112 insertions, 2 deletions
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index 61304cb..94ea99d 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,13 @@ +2016-09-26 Marek Polacek <polacek@redhat.com> + Jakub Jelinek <jakub@redhat.com> + + PR c/7652 + * include/cpplib.h (PREV_FALLTHROUGH): Define. + * internal.h (CPP_FALLTHRU): Define. + * lex.c (fallthrough_comment_p): New function. + (_cpp_lex_direct): Set PREV_FALLTHROUGH on tokens succeeding a falls + through comment. + 2016-09-23 David Malcolm <dmalcolm@redhat.com> PR preprocessor/77672 diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h index cfc6ccd..6352ac5 100644 --- a/libcpp/include/cpplib.h +++ b/libcpp/include/cpplib.h @@ -185,7 +185,8 @@ struct GTY(()) cpp_string { #define STRINGIFY_ARG (1 << 2) /* If macro argument to be stringified. */ #define PASTE_LEFT (1 << 3) /* If on LHS of a ## operator. */ #define NAMED_OP (1 << 4) /* C++ named operators. */ -#define NO_EXPAND (1 << 5) /* Do not macro-expand this token. */ +#define PREV_FALLTHROUGH (1 << 5) /* On a token preceeded by FALLTHROUGH + comment. */ #define BOL (1 << 6) /* Token at beginning of line. */ #define PURE_ZERO (1 << 7) /* Single 0 digit, used by the C++ frontend, set in c-lex.c. */ @@ -193,6 +194,7 @@ struct GTY(()) cpp_string { #define SP_PREV_WHITE (1 << 9) /* If whitespace before a ## operator, or before this token after a # operator. */ +#define NO_EXPAND (1 << 10) /* Do not macro-expand this token. */ /* Specify which field, if any, of the cpp_token union is used. */ diff --git a/libcpp/lex.c b/libcpp/lex.c index 6254ed6..0c47e29 100644 --- a/libcpp/lex.c +++ b/libcpp/lex.c @@ -2032,6 +2032,94 @@ save_comment (cpp_reader *pfile, cpp_token *token, const unsigned char *from, store_comment (pfile, token); } +/* Returns true if comment at COMMENT_START is a recognized FALLTHROUGH + comment. */ + +static bool +fallthrough_comment_p (cpp_reader *pfile, const unsigned char *comment_start) +{ + const unsigned char *from = comment_start + 1; + /* Whole comment contents: + -fallthrough + @fallthrough@ + */ + if (*from == '-' || *from == '@') + { + size_t len = sizeof "fallthrough" - 1; + if ((size_t) (pfile->buffer->cur - from - 1) < len) + return false; + if (memcmp (from + 1, "fallthrough", len)) + return false; + if (*from == '@') + { + if (from[len + 1] != '@') + return false; + len++; + } + from += 1 + len; + } + /* Whole comment contents (regex): + [ \t]*FALL(S | |-)?THR(OUGH|U)\.?[ \t]* + [ \t]*Fall(s | |-)?[Tt]hr(ough|u)\.?[ \t]* + [ \t]*fall(s | |-)?thr(ough|u)\.?[ \t]* + */ + else + { + while (*from == ' ' || *from == '\t') + from++; + unsigned char f = *from; + if (f != 'F' && f != 'f') + return false; + if ((size_t) (pfile->buffer->cur - from) < sizeof "fallthrough") + 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')) + 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") + return false; + if (memcmp (from + 1, all_upper ? "HRU" : "hru", sizeof "hru" - 1)) + { + if ((size_t) (pfile->buffer->cur - from) < sizeof "through") + return false; + if (memcmp (from + 1, all_upper ? "HROUGH" : "hrough", + sizeof "hrough" - 1)) + return false; + from += sizeof "through" - 1; + } + else + from += sizeof "thru" - 1; + if (*from == '.') + from++; + while (*from == ' ' || *from == '\t') + from++; + } + /* C block comment. */ + if (*comment_start == '*') + { + if (*from != '*' || from[1] != '/') + return false; + } + /* C++ line comment. */ + else if (*from != '\n') + return false; + + return true; +} + /* Allocate COUNT tokens for RUN. */ void _cpp_init_tokenrun (tokenrun *run, unsigned int count) @@ -2310,7 +2398,7 @@ _cpp_lex_direct (cpp_reader *pfile) { cppchar_t c; cpp_buffer *buffer; - const unsigned char *comment_start; + const unsigned char *comment_start = NULL; cpp_token *result = pfile->cur_token++; fresh_line: @@ -2337,6 +2425,8 @@ _cpp_lex_direct (cpp_reader *pfile) } return result; } + if (buffer != pfile->buffer) + comment_start = NULL; if (!pfile->keep_tokens) { pfile->cur_run = &pfile->base_run; @@ -2443,6 +2533,11 @@ _cpp_lex_direct (cpp_reader *pfile) result->flags |= NAMED_OP; result->type = (enum cpp_ttype) result->val.node.node->directive_index; } + + /* Signal FALLTHROUGH comment followed by another token. */ + if (comment_start + && fallthrough_comment_p (pfile, comment_start)) + result->flags |= PREV_FALLTHROUGH; break; case '\'': @@ -2534,6 +2629,9 @@ _cpp_lex_direct (cpp_reader *pfile) goto update_tokens_line; } + if (fallthrough_comment_p (pfile, comment_start)) + result->flags |= PREV_FALLTHROUGH; + /* Save the comment as a token in its own right. */ save_comment (pfile, result, comment_start, c); break; |