[patch] Fix PR 20563: Parser hiccups on invalid __label__ declaration

Volker Reichelt reichelt@igpm.rwth-aachen.de
Tue Jun 7 19:56:00 GMT 2005


When parsing a __label__ declaration with an invalid or missing label,
the compiler either ICE's (with --enable-checking) or runs into an
infinite loop (with --disable-checking).

This is due to the following loop in cp_parser_label_declaration:

    while (true)
      {
        tree identifier;

        /* Look for an identifier.  */
        identifier = cp_parser_identifier (parser);
        /* Declare it as a lobel.  */
        finish_label_decl (identifier);
        /* If the next token is a `;', stop.  */
        if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
	  break;
        /* Look for the `,' separating the label declarations.  */
        cp_parser_require (parser, CPP_COMMA, "`,'");
      }

If we encounter an invalid or missing label, IDENTIFIER will be an
ERROR_MARK_NODE. In the --enable-checking case this will cause
a tree check failure in FINISH_LABEL_DECL.
In the --disable-checking FINISH_LABEL_DECL does not complain, but
the parser still looks at the invalid token. Since this is usually
not a CPP_SEMICOLON or a CPP_COMMA the parser is not able to consume
any more tokens and runs through the loop forever.

The following patch fixes both cases by quitting the loop in case
IDENTIFIER is an ERROR_MARK_NODE.

It fixes a typo in a comment ("lobel" instead of "label"), too.

Bootstrapped and regtested on i686-pc-linux-gnu.
Ok for 3.4 branch, 4.0 branch (since it's a regression) and mainline?

Regards,
Volker


2005-06-07  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>

	PR c++/20563
	* parser.c (cp_parser_label_declaration): Deal with invalid/missing
        identifiers.

============================================================================
--- gcc/gcc/cp/parser.c	2005-06-07 03:18:27.000000000 +0200
+++ gcc/gcc/cp/parser.c	2005-06-07 03:18:44.000000000 +0200
@@ -14231,7 +14231,10 @@ cp_parser_label_declaration (cp_parser* 
 
       /* Look for an identifier.  */
       identifier = cp_parser_identifier (parser);
-      /* Declare it as a lobel.  */
+      /* If we failed, stop.  */
+      if (identifier == error_mark_node)
+	break;
+      /* Declare it as a label.  */
       finish_label_decl (identifier);
       /* If the next token is a `;', stop.  */
       if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
============================================================================


2005-06-07  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>

	PR c++/20563
	* g++.dg/ext/label4.C: New test.

============================================================================
--- gcc/gcc/testsuite/g++.dg/ext/label4.C	2005-05-27 23:07:43.000000000 +0200
+++ gcc/gcc/testsuite/g++.dg/ext/label4.C	2005-06-07 18:09:12.000000000 +0200
@@ -0,0 +1,6 @@
+// PR c++/20563: ICE (--enable-checking), infinite loop (--disable-checking)
+// Origin:       Giovanni Bajo <giovannibajo@libero.it>
+
+// { dg-do compile }
+
+__label__ *l;  // { dg-error "before" }
============================================================================




More information about the Gcc-patches mailing list