diff options
-rw-r--r-- | gcc/cp/parser.c | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/gen-attrs-76.C | 31 |
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" } +} |