aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/parser.c25
-rw-r--r--gcc/testsuite/ChangeLog9
-rw-r--r--gcc/testsuite/g++.dg/ext/label4.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/label6.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/label7.C12
-rw-r--r--gcc/testsuite/g++.dg/ext/label8.C22
-rw-r--r--gcc/testsuite/g++.dg/ext/label9.C10
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" }
+}