aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/parser.c11
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/gen-attrs-76.C31
2 files changed, 38 insertions, 4 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index d960d38..97078f9 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -11904,6 +11904,7 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
cp_token *token;
location_t statement_location, attrs_loc;
bool in_omp_attribute_pragma = parser->lexer->in_omp_attribute_pragma;
+ bool has_std_attrs;
restart:
if (if_p != NULL)
@@ -11912,7 +11913,8 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
statement = NULL_TREE;
saved_token_sentinel saved_tokens (parser->lexer);
- attrs_loc = cp_lexer_peek_token (parser->lexer)->location;
+ token = cp_lexer_peek_token (parser->lexer);
+ attrs_loc = token->location;
if (c_dialect_objc ())
/* In obj-c++, seeing '[[' might be the either the beginning of
c++11 attributes, or a nested objc-message-expression. So
@@ -11926,6 +11928,7 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
if (!cp_parser_parse_definitely (parser))
std_attrs = NULL_TREE;
}
+ has_std_attrs = cp_lexer_peek_token (parser->lexer) != token;
if (std_attrs && (flag_openmp || flag_openmp_simd))
std_attrs = cp_parser_handle_statement_omp_attributes (parser, std_attrs);
@@ -11994,7 +11997,7 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
case RID_NAMESPACE:
/* This must be a namespace alias definition. */
- if (std_attrs != NULL_TREE)
+ if (has_std_attrs)
{
/* Attributes should be parsed as part of the
declaration, so let's un-parse them. */
@@ -12099,7 +12102,7 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
{
if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
{
- if (std_attrs != NULL_TREE)
+ if (has_std_attrs)
/* Attributes should be parsed as part of the declaration,
so let's un-parse them. */
saved_tokens.rollback();
@@ -12111,7 +12114,7 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
if (cp_parser_parse_definitely (parser))
return;
/* It didn't work, restore the post-attribute position. */
- if (std_attrs)
+ if (has_std_attrs)
cp_lexer_set_token_position (parser->lexer, statement_token);
}
/* All preceding labels have been parsed at this point. */
diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-76.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-76.C
new file mode 100644
index 0000000..cbda8de
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-76.C
@@ -0,0 +1,31 @@
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wno-attributes" }
+
+namespace N {}
+namespace O { typedef int T; };
+
+void
+foo ()
+{
+ [[]] asm (""); // { dg-error "expected" }
+ [[]] __extension__ asm (""); // { dg-error "expected" }
+ __extension__ [[]] asm (""); // { dg-error "expected" }
+ [[]] namespace M = ::N; // { dg-error "expected" }
+ [[]] using namespace N; // { dg-bogus "expected" "" { xfail *-*-* } }
+ [[]] using O::T; // { dg-error "expected" }
+ [[]] __label__ foo; // { dg-error "expected" }
+ [[]] static_assert (true, ""); // { dg-error "expected" }
+}
+
+void
+bar ()
+{
+ [[gnu::unused]] asm (""); // { dg-error "expected" }
+ [[gnu::unused]] __extension__ asm (""); // { dg-error "expected" }
+ __extension__ [[gnu::unused]] asm (""); // { dg-error "expected" }
+ [[gnu::unused]] namespace M = ::N; // { dg-error "expected" }
+ [[gnu::unused]] using namespace N; // { dg-bogus "expected" "" { xfail *-*-* } }
+ [[gnu::unused]] using O::T; // { dg-error "expected" }
+ [[gnu::unused]] __label__ foo; // { dg-error "expected" }
+ [[gnu::unused]] static_assert (true, ""); // { dg-error "expected" }
+}