aboutsummaryrefslogtreecommitdiff
path: root/libcpp
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2016-09-26 09:42:50 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2016-09-26 09:42:50 +0000
commit81fea426da8c4687bb32e6894dc26f00ae211822 (patch)
tree8b84b3de175727d09b7dcf1b5703e0d46b64f9e7 /libcpp
parent392fa55c799358e198ca85fbea548e60359133c5 (diff)
downloadgcc-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/ChangeLog10
-rw-r--r--libcpp/include/cpplib.h4
-rw-r--r--libcpp/lex.c100
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;