From 1a59ccf25df49415490423382d31db15fa9c7796 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Wed, 25 Oct 2017 23:53:41 +0000 Subject: C: detect more missing semicolons (PR c/7356) c_parser_declaration_or_fndef has logic for parsing what might be either a declaration or a function definition. This patch adds a test to detect cases where a semicolon would have terminated the decls as a declaration, where the token that follows would start a new declaration specifier, and updates the error message accordingly, with a fix-it hint. This addresses PR c/7356, fixing the case of a stray token before a #include that previously gave inscrutable output, and improving e.g.: int i int j; from: t.c:2:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'int' int j; ^~~ to: t.c:1:6: error: expected ';' before 'int' int i ^ ; int j; ~~~ gcc.dg/noncompile/920923-1.c needs a slight update, as the output for the first line changes from: 920923-1.c:2:14: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'unsigned' typedef BYTE unsigned char; /* { dg-error "expected" } */ ^~~~~~~~ to: 920923-1.c:2:13: error: expected ';' before 'unsigned' typedef BYTE unsigned char; /* { dg-error "expected" } */ ^~~~~~~~~ ; 920923-1.c:2:1: warning: useless type name in empty declaration typedef BYTE unsigned char; /* { dg-error "expected" } */ ^~~~~~~ The patch also adds a test for PR c/44515 as a baseline. gcc/c/ChangeLog: PR c/7356 * c-parser.c (c_parser_declaration_or_fndef): Detect missing semicolons. gcc/testsuite/ChangeLog: PR c/7356 PR c/44515 * c-c++-common/pr44515.c: New test case. * gcc.dg/pr7356-2.c: New test case. * gcc.dg/pr7356.c: New test case. * gcc.dg/spellcheck-typenames.c: Update the "singed" char "TODO" case to reflect changes to output. * gcc.dg/noncompile/920923-1.c: Add dg-warning to reflect changes to output. From-SVN: r254093 --- gcc/c/ChangeLog | 6 ++++++ gcc/c/c-parser.c | 36 +++++++++++++++++++++++++++++++----- 2 files changed, 37 insertions(+), 5 deletions(-) (limited to 'gcc/c') diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index b4fde0d..5d028b4 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2017-10-25 David Malcolm + + PR c/7356 + * c-parser.c (c_parser_declaration_or_fndef): Detect missing + semicolons. + 2017-10-25 Jakub Jelinek PR libstdc++/81706 diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 6b84324..68c45fd 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -2241,11 +2241,37 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, } if (!start_function (specs, declarator, all_prefix_attrs)) { - /* This can appear in many cases looking nothing like a - function definition, so we don't give a more specific - error suggesting there was one. */ - c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, % " - "or %<__attribute__%>"); + /* At this point we've consumed: + declaration-specifiers declarator + and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON, + RID_ASM, RID_ATTRIBUTE, or RID_IN, + but the + declaration-specifiers declarator + aren't grokkable as a function definition, so we have + an error. */ + gcc_assert (!c_parser_next_token_is (parser, CPP_SEMICOLON)); + if (c_parser_next_token_starts_declspecs (parser)) + { + /* If we have + declaration-specifiers declarator decl-specs + then assume we have a missing semicolon, which would + give us: + declaration-specifiers declarator decl-specs + ^ + ; + <~~~~~~~~~ declaration ~~~~~~~~~~> + Use c_parser_require to get an error with a fix-it hint. */ + c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"); + parser->error = false; + } + else + { + /* This can appear in many cases looking nothing like a + function definition, so we don't give a more specific + error suggesting there was one. */ + c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, % " + "or %<__attribute__%>"); + } if (nested) c_pop_function_context (); break; -- cgit v1.1