[C++ PATCH] parser simplification
authorNathan Sidwell <nathan@acm.org>
Thu, 11 Oct 2018 18:58:55 +0000 (18:58 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Thu, 11 Oct 2018 18:58:55 +0000 (18:58 +0000)
https://gcc.gnu.org/ml/gcc-patches/2018-10/msg00689.html
cp/
* parser.c (cp_parser_translation_unit): Return void.  Don't fail
at first extra }, simplify logic.
(c_parse_file): Call finish_translation_unit here.

testsuite/
* g++.dg/parse/close-brace.C: New.
* g++.dg/cpp0x/noexcept16.C: Avoid warning.
* g++.old-deja/g++.other/crash32.C: Add another error

From-SVN: r265055

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/noexcept16.C
gcc/testsuite/g++.dg/parse/close-brace.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.other/crash32.C

index 9ec7c8b861cc8d0a5ba8a45b43724cdb1cbf084f..da443d9be407d0d06afc871ac48a5346a2cb5272 100644 (file)
@@ -1,3 +1,9 @@
+2018-10-11  Nathan Sidwell  <nathan@acm.org>
+
+       * parser.c (cp_parser_translation_unit): Return void.  Don't fail
+       at first extra }, simplify logic.
+       (c_parse_file): Call finish_translation_unit here.
+
 2018-10-11  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/87582
index 5e83b20360a293037bfb6e86f29b67653b6c2514..76ff83616b0395cf600a5bb2f0c87ffd9323ca59 100644 (file)
@@ -2015,8 +2015,7 @@ static cp_expr cp_parser_userdef_numeric_literal
 
 /* Basic concepts [gram.basic]  */
 
-static bool cp_parser_translation_unit
-  (cp_parser *);
+static void cp_parser_translation_unit (cp_parser *);
 
 /* Expressions [gram.expr]  */
 
@@ -4585,66 +4584,52 @@ cp_parser_userdef_string_literal (tree literal)
 /* Parse a translation-unit.
 
    translation-unit:
-     declaration-seq [opt]
-
-   Returns TRUE if all went well.  */
+     declaration-seq [opt]  */
 
-static bool
+static void
 cp_parser_translation_unit (cp_parser* parser)
 {
-  /* The address of the first non-permanent object on the declarator
-     obstack.  */
-  static void *declarator_obstack_base;
-
-  bool success;
+  gcc_checking_assert (!cp_error_declarator);
+  
+  /* Create the declarator obstack.  */
+  gcc_obstack_init (&declarator_obstack);
+  /* Create the error declarator.  */
+  cp_error_declarator = make_declarator (cdk_error);
+  /* Create the empty parameter list.  */
+  no_parameters = make_parameter_declarator (NULL, NULL, NULL_TREE,
+                                            UNKNOWN_LOCATION);
+  /* Remember where the base of the declarator obstack lies.  */
+  void *declarator_obstack_base = obstack_next_free (&declarator_obstack);
 
-  /* Create the declarator obstack, if necessary.  */
-  if (!cp_error_declarator)
+  for (;;)
     {
-      gcc_obstack_init (&declarator_obstack);
-      /* Create the error declarator.  */
-      cp_error_declarator = make_declarator (cdk_error);
-      /* Create the empty parameter list.  */
-      no_parameters = make_parameter_declarator (NULL, NULL, NULL_TREE,
-                                                UNKNOWN_LOCATION);
-      /* Remember where the base of the declarator obstack lies.  */
-      declarator_obstack_base = obstack_next_free (&declarator_obstack);
+      cp_parser_declaration_seq_opt (parser);
+      gcc_assert (!cp_parser_parsing_tentatively (parser));
+      if (cp_lexer_next_token_is (parser->lexer, CPP_EOF))
+       break;
+      /* Must have been an extra close-brace.  */
+      cp_parser_error (parser, "expected declaration");
+      cp_lexer_consume_token (parser->lexer);
+      /* If the next token is now a `;', consume it.  */
+      if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+       cp_lexer_consume_token (parser->lexer);
     }
 
-  cp_parser_declaration_seq_opt (parser);
-
-  /* If there are no tokens left then all went well.  */
-  if (cp_lexer_next_token_is (parser->lexer, CPP_EOF))
-    {
-      /* Get rid of the token array; we don't need it any more.  */
-      cp_lexer_destroy (parser->lexer);
-      parser->lexer = NULL;
-
-      /* This file might have been a context that's implicitly extern
-        "C".  If so, pop the lang context.  (Only relevant for PCH.) */
-      if (parser->implicit_extern_c)
-       {
-         pop_lang_context ();
-         parser->implicit_extern_c = false;
-       }
-
-      /* Finish up.  */
-      finish_translation_unit ();
-
-      success = true;
-    }
-  else
+  /* Get rid of the token array; we don't need it any more.  */
+  cp_lexer_destroy (parser->lexer);
+  parser->lexer = NULL;
+  
+  /* This file might have been a context that's implicitly extern
+     "C".  If so, pop the lang context.  (Only relevant for PCH.) */
+  if (parser->implicit_extern_c)
     {
-      cp_parser_error (parser, "expected declaration");
-      success = false;
+      pop_lang_context ();
+      parser->implicit_extern_c = false;
     }
 
   /* Make sure the declarator obstack was fully cleaned up.  */
   gcc_assert (obstack_next_free (&declarator_obstack)
              == declarator_obstack_base);
-
-  /* All went well.  */
-  return success;
 }
 
 /* Return the appropriate tsubst flags for parsing, possibly in N3276
@@ -39130,6 +39115,8 @@ c_parse_file (void)
                                ? dk_no_deferred : dk_no_check);
   cp_parser_translation_unit (the_parser);
   the_parser = NULL;
+
+  finish_translation_unit ();
 }
 
 /* Create an identifier for a generic parameter type (a synthesized
index 4bca601358fc82de8691406e9f593a045e730b79..df8f70c671e62689d080e51fd9720263dfd8114b 100644 (file)
@@ -1,3 +1,9 @@
+2018-10-11  Nathan Sidwell  <nathan@acm.org>
+
+       * g++.dg/parse/close-brace.C: New.
+       * g++.dg/cpp0x/noexcept16.C: Avoid warning.
+       * g++.old-deja/g++.other/crash32.C: Add another error
+
 2018-10-11  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/85070
index 10e0be9588798b70bc13fd42580e4d502e3e680a..873d9b2c48ee8edc9130cdaebcba3810cc2ff8b9 100644 (file)
@@ -124,7 +124,7 @@ swap(_Tp&, _Tp&)
   ;
 typedef lexertl::basic_state_machine<char32_t> lexstate;
 lexstate m_state_machine;
-GenerateLexer()
+void GenerateLexer()
 {
   m_state_machine.minimise();
 }
diff --git a/gcc/testsuite/g++.dg/parse/close-brace.C b/gcc/testsuite/g++.dg/parse/close-brace.C
new file mode 100644 (file)
index 0000000..3dde6b3
--- /dev/null
@@ -0,0 +1,5 @@
+// We used to stop parsing at the first top-level '}' !
+
+} // { dg-error "expected declaration" }
+
+float int c; // { dg-error "two or more data types" }
index b9c4cf98c0652301f31da8e851dcec22f069b33e..d0b68db744ab699543ae980c335746a97209f14c 100644 (file)
@@ -5,7 +5,9 @@ struct foo
 {
   enum e
   {
-    not                                // { dg-error "" } 
+    not                                // { dg-error "" }
+    // We think the next close-brace closes the definition of struct
+    // foo, not enum e.  Things go downhill from there
   }; // { dg-bogus "" } 
   ~foo(); // { dg-bogus "" "" { xfail *-*-* } } 
   void x (foo *&a, bool b = (unsigned char)0);
@@ -24,6 +26,6 @@ namespace N
   typedef baz<bar> c;
 }
 
-{
+{ // { dg-error "expected" }
   int a;
 };