diff options
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/parser.c | 25 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/label4.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/label6.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/label7.C | 12 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/label8.C | 22 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/label9.C | 10 |
8 files changed, 83 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1aeacba..faea90d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2007-10-12 Jakub Jelinek <jakub@redhat.com> + + PR c++/32121 + * parser.c (cp_parser_compound_statement): Handle label-declarations + at the beginning of the compound statement. + (cp_parser_block_declaration): Issue diagnostics about __label__ + not at the beginning of a block. + 2007-10-11 Paolo Carlini <pcarlini@suse.de> PR c++/33461 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 3720b55..3fab4dc 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -6821,6 +6821,15 @@ cp_parser_expression_statement (cp_parser* parser, tree in_statement_expr) compound-statement: { statement-seq [opt] } + GNU extension: + + compound-statement: + { label-declaration-seq [opt] statement-seq [opt] } + + label-declaration-seq: + label-declaration + label-declaration-seq label-declaration + Returns a tree representing the statement. */ static tree @@ -6834,6 +6843,9 @@ cp_parser_compound_statement (cp_parser *parser, tree in_statement_expr, return error_mark_node; /* Begin the compound-statement. */ compound_stmt = begin_compound_stmt (in_try ? BCS_TRY_BLOCK : 0); + /* If the next keyword is `__label__' we have a label declaration. */ + while (cp_lexer_next_token_is_keyword (parser->lexer, RID_LABEL)) + cp_parser_label_declaration (parser); /* Parse an (optional) statement-seq. */ cp_parser_statement_seq_opt (parser, in_statement_expr); /* Finish the compound-statement. */ @@ -7711,7 +7723,6 @@ cp_parser_declaration (cp_parser* parser) block-declaration: __extension__ block-declaration - label-declaration C++0x Extension: @@ -7772,12 +7783,16 @@ cp_parser_block_declaration (cp_parser *parser, cp_parser_using_declaration (parser, /*access_declaration_p=*/false); } - /* If the next keyword is `__label__' we have a label declaration. */ + /* If the next keyword is `__label__' we have a misplaced label + declaration. */ else if (token1->keyword == RID_LABEL) { - if (statement_p) - cp_parser_commit_to_tentative_parse (parser); - cp_parser_label_declaration (parser); + cp_lexer_consume_token (parser->lexer); + error ("%<__label__%> not at the beginning of a block"); + cp_parser_skip_to_end_of_statement (parser); + /* 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); } /* If the next token is `static_assert' we have a static assertion. */ else if (token1->keyword == RID_STATIC_ASSERT) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3041b96..7434c1e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2007-10-12 Jakub Jelinek <jakub@redhat.com> + + PR c++/32121 + * g++.dg/ext/label4.C: Adjust error regexp. + * g++.dg/ext/label6.C: Adjust error regexp. + * g++.dg/ext/label7.C: New test. + * g++.dg/ext/label8.C: New test. + * g++.dg/ext/label9.C: New test. + 2007-10-11 Kenneth Zadeck <zadeck@naturalbridge.com> PR middle-end/33676 diff --git a/gcc/testsuite/g++.dg/ext/label4.C b/gcc/testsuite/g++.dg/ext/label4.C index 80b50a7..93f140f 100644 --- a/gcc/testsuite/g++.dg/ext/label4.C +++ b/gcc/testsuite/g++.dg/ext/label4.C @@ -3,4 +3,4 @@ // { dg-do compile } -__label__ *l; // { dg-error "before" } +__label__ *l; // { dg-error "not at the beginning of" } diff --git a/gcc/testsuite/g++.dg/ext/label6.C b/gcc/testsuite/g++.dg/ext/label6.C index d026777..e4b0c37c 100644 --- a/gcc/testsuite/g++.dg/ext/label6.C +++ b/gcc/testsuite/g++.dg/ext/label6.C @@ -1,3 +1,3 @@ // PR c++/32108 -__label__ L; // { dg-error "function scopes" } +__label__ L; // { dg-error "not at the beginning" } diff --git a/gcc/testsuite/g++.dg/ext/label7.C b/gcc/testsuite/g++.dg/ext/label7.C new file mode 100644 index 0000000..e92dccf --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/label7.C @@ -0,0 +1,12 @@ +// PR c++/32121 +// { dg-do compile } + +int f (void) +{ + a:; + __label__ a; // { dg-error "not at the beginning" } + int b; + __label__ c; // { dg-error "not at the beginning" } + a:; // { dg-error "duplicate label" } + c:; +} diff --git a/gcc/testsuite/g++.dg/ext/label8.C b/gcc/testsuite/g++.dg/ext/label8.C new file mode 100644 index 0000000..1f6175d --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/label8.C @@ -0,0 +1,22 @@ +// PR c++/32121 +// { dg-do compile } + +int f (void) +{ + __label__ a, b; + __label__ c; + a:; + b:; + c:; + { + __label__ d; + d:; + if (0) + { + __label__ e; + __label__ f; + f:; + e:; + } + } +} diff --git a/gcc/testsuite/g++.dg/ext/label9.C b/gcc/testsuite/g++.dg/ext/label9.C new file mode 100644 index 0000000..81b385f --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/label9.C @@ -0,0 +1,10 @@ +// PR c++/32121 +// { dg-do compile } + +int f (void) +{ + while (1) + __label__ a; // { dg-error "not at the beginning" } + for (;;) + __label__ b; // { dg-error "not at the beginning" } +} |