This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC] PR c/23722 bad error recovery with if blocks and else


:ADDPATCH c:

A much nicer version of the patch. Also, using explicit locations as
Tom requested.

Bootstrapped and regression tested. OK to commit?

2007-11-22  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>

  PR c/23722
 * c-parser.c (struct c_parser): New bit in_if_stmt.
  (c_parser_compound_statement_nostart): Handle unexpected 'else' keyword.

testsuite/
 * gcc.dg/cpp/19990413-1.c: Update.
 * gcc.dg/parse-else-error.c: New.
 * gcc.dg/parse-else-error-2.c: New.
 * gcc.dg/parse-else-error-3.c: New.
Index: gcc/testsuite/gcc.dg/parse-else-error.c
===================================================================
--- gcc/testsuite/gcc.dg/parse-else-error.c	(revision 0)
+++ gcc/testsuite/gcc.dg/parse-else-error.c	(revision 0)
@@ -0,0 +1,12 @@
+/* PR 23722 */
+/* { dg-do compile } */
+/* { dg-options "-fsyntax-only" } */
+int f()
+{
+  if (1)
+  {
+   return 1;
+  else /* { dg-error "expected .\}. before 'else'" } */
+  {
+  }
+}
Index: gcc/testsuite/gcc.dg/parse-else-error-3.c
===================================================================
--- gcc/testsuite/gcc.dg/parse-else-error-3.c	(revision 0)
+++ gcc/testsuite/gcc.dg/parse-else-error-3.c	(revision 0)
@@ -0,0 +1,11 @@
+/* PR 23722 */
+/* { dg-do compile } */
+/* { dg-options "-fsyntax-only" } */
+int f()
+{
+
+  else  /* { dg-error "'else' without a previous 'if'" } */
+    {
+      return 0;
+    }
+}
Index: gcc/testsuite/gcc.dg/cpp/19990413-1.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/19990413-1.c	(revision 130174)
+++ gcc/testsuite/gcc.dg/cpp/19990413-1.c	(working copy)
@@ -9,5 +9,5 @@ func(void)
 {
   FOO(i
       = 4)
-  else;  /* { dg-error "parse error|syntax error|expected" "error on this line" { target *-*-* } { 12 } } */ 
+  else;  /* { dg-error "'else' without a previous 'if'" "error on this line" { target *-*-* } { 12 } } */ 
 }
Index: gcc/testsuite/gcc.dg/parse-else-error-2.c
===================================================================
--- gcc/testsuite/gcc.dg/parse-else-error-2.c	(revision 0)
+++ gcc/testsuite/gcc.dg/parse-else-error-2.c	(revision 0)
@@ -0,0 +1,13 @@
+/* PR 23722 */
+/* { dg-do compile } */
+/* { dg-options "-fsyntax-only" } */
+int f()
+{
+  if (1)
+    {
+      return 1;
+  else /* { dg-error "expected .\}. before 'else'" } */
+  {
+      }
+  }
+} /* { dg-error "expected identifier or '\\(' before .\}. token" } */
Index: gcc/c-parser.c
===================================================================
--- gcc/c-parser.c	(revision 130174)
+++ gcc/c-parser.c	(working copy)
@@ -280,6 +280,8 @@ typedef struct c_parser GTY(())
   /* True if we're processing a pragma, and shouldn't automatically
      consume CPP_PRAGMA_EOL.  */
   BOOL_BITFIELD in_pragma : 1;
+  /* True if we're processing the body of an if statement.  */
+  BOOL_BITFIELD in_if_stmt : 1;
   /* True if we want to lex an untranslated string.  */
   BOOL_BITFIELD lex_untranslated_string : 1;
   /* Objective-C specific parser/lexer information.  */
@@ -3541,6 +3543,20 @@ c_parser_compound_statement_nostart (c_p
 	  c_parser_error (parser, "expected declaration or statement");
 	  return;
 	}
+      else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
+        {
+          if (parser->in_if_stmt) 
+            {
+              error ("%H""expected %<}%> before %<else%>", &loc);
+              return;
+            }
+          else 
+            {
+              error ("%H%<else%> without a previous %<if%>", &loc);
+              c_parser_consume_token (parser);
+              continue;
+            }
+        }
       else
 	{
 	statement:
@@ -3915,7 +3931,11 @@ c_parser_c99_block_statement (c_parser *
 static tree
 c_parser_if_body (c_parser *parser, bool *if_p)
 {
-  tree block = c_begin_compound_stmt (flag_isoc99);
+  tree block;
+  bool in_if_stmt = parser->in_if_stmt;
+
+  parser->in_if_stmt = true;
+  block = c_begin_compound_stmt (flag_isoc99);
   while (c_parser_next_token_is_keyword (parser, RID_CASE)
 	 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
 	 || (c_parser_next_token_is (parser, CPP_NAME)
@@ -3925,6 +3945,7 @@ c_parser_if_body (c_parser *parser, bool
   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
     add_stmt (build_empty_stmt ());
   c_parser_statement_after_labels (parser);
+  parser->in_if_stmt = in_if_stmt;
   return c_end_compound_stmt (block, flag_isoc99);
 }
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]