[PATCH,c++] fix PR 46868, segfault after bogus semicolon recovery

Nathan Froyd froydnj@codesourcery.com
Thu Feb 3 19:54:00 GMT 2011


On Wed, Jan 05, 2011 at 02:38:23PM -0500, Jason Merrill wrote:
> How about if we only attempt semicolon recovery if we actually saw
> the closing brace?

OK, how about this?  Tested x86_64-unknown-linux-gnu.

-Nathan

gcc/cp/
	PR c++/46868
	* parser.c (cp_parser_class_specifier): Require a closing brace
	to attempt error recovery.

gcc/testsuite/
	PR c++/46868
	* g++.dg/pr46868.C: New test.
	* g++.dg/parse/parameter-declaration-1.C: Adjust.
	* g++.dg/parse/error14.C: Adjust.

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 11039b8..4665f0d 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -16870,6 +16870,7 @@ cp_parser_class_specifier (cp_parser* parser)
   tree old_scope = NULL_TREE;
   tree scope = NULL_TREE;
   tree bases;
+  cp_token *closing_brace;
 
   push_deferring_access_checks (dk_no_deferred);
 
@@ -16939,7 +16940,7 @@ cp_parser_class_specifier (cp_parser* parser)
     cp_parser_member_specification_opt (parser);
 
   /* Look for the trailing `}'.  */
-  cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+  closing_brace = cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
   /* Look for trailing attributes to apply to this class.  */
   if (cp_parser_allow_gnu_extensions_p (parser))
     attributes = cp_parser_attributes_opt (parser);
@@ -17014,8 +17015,9 @@ cp_parser_class_specifier (cp_parser* parser)
       }
 
     /* If we don't have a type, then something is very wrong and we
-       shouldn't try to do anything clever.  */
-    if (TYPE_P (type) && want_semicolon)
+       shouldn't try to do anything clever.  Likewise for not seeing the
+       closing brace.  */
+    if (closing_brace && TYPE_P (type) && want_semicolon)
       {
 	cp_token_position prev
 	  = cp_lexer_previous_token_position (parser->lexer);
diff --git a/gcc/testsuite/g++.dg/parse/error14.C b/gcc/testsuite/g++.dg/parse/error14.C
index 37abe37..04f2f56 100644
--- a/gcc/testsuite/g++.dg/parse/error14.C
+++ b/gcc/testsuite/g++.dg/parse/error14.C
@@ -21,6 +21,6 @@ struct X
 
 }; // { dg-error "2:expected '.' at end of input" "at end of input" }
    // { dg-error "1:expected primary-expression before '.' token" "primary" { target *-*-* } 22 }
-   // { dg-error "2:expected ';' after struct definition" "semicolon" { target *-*-* } 22 }
+   // { dg-error "1:expected unqualified-id" "unqualified-id" { target *-*-* } 22 }
    // { dg-error "1:expected ';' before '.' token" "function" { target *-*-* } 22 }
 
diff --git a/gcc/testsuite/g++.dg/parse/parameter-declaration-1.C b/gcc/testsuite/g++.dg/parse/parameter-declaration-1.C
index 58f6799..22d6f21 100644
--- a/gcc/testsuite/g++.dg/parse/parameter-declaration-1.C
+++ b/gcc/testsuite/g++.dg/parse/parameter-declaration-1.C
@@ -2,5 +2,5 @@
 // Origin: Robert Schiele; PR C++/8799
 // { dg-do compile }
 
-struct {			// { dg-error "" }
+struct {
    a(void = 0; a(0), a(0)	// { dg-error "" "" { target *-*-* } }
diff --git a/gcc/testsuite/g++.dg/pr46868.C b/gcc/testsuite/g++.dg/pr46868.C
new file mode 100644
index 0000000..544c7b2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr46868.C
@@ -0,0 +1,4 @@
+// PR c++/46868
+// { dg-do compile }
+
+template < int > struct S { S < // { dg-error "" }



More information about the Gcc-patches mailing list