diff options
author | Jakub Jelinek <jakub@redhat.com> | 2021-08-12 09:09:39 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2021-08-12 09:34:16 +0200 |
commit | 3890c28ac5bd03ba334a20fbf9518a37dcdbfe5d (patch) | |
tree | c0a6bd0d91ec9e3b4e1890f30ab3f67cea95a467 /gcc/cp | |
parent | 2bdf17de1d0ad7a75d3474e672a3a2110919862f (diff) | |
download | gcc-3890c28ac5bd03ba334a20fbf9518a37dcdbfe5d.zip gcc-3890c28ac5bd03ba334a20fbf9518a37dcdbfe5d.tar.gz gcc-3890c28ac5bd03ba334a20fbf9518a37dcdbfe5d.tar.bz2 |
c++: Fix up parsing of attributes for using-directive
As I've said earlier and added xfails in gen-attrs-76.C test,
https://eel.is/c++draft/namespace.udir#nt:using-directive
has attribute-specifier-seq[opt] at the start, not at the end before ;
as gcc is expecting.
IMHO we should continue parsing at the end the GNU attributes
because using namespace N __attribute__((strong));, while not supported
anymore, used to be supported in the past, but my code searches for
using namespace N [[gnu::strong]]; didn't reveal anything at all.
2021-08-12 Jakub Jelinek <jakub@redhat.com>
* parser.c (cp_parser_block_declaration): Call
cp_parser_using_directive for C++11 attributes followed by
using namespace tokens.
(cp_parser_using_directive): Parse C++11 attributes at the start
of the directive rather than at the end, only parse GNU attributes
at the end.
* g++.dg/lookup/strong-using.C: Add test using [[gnu::strong]]
as well.
* g++.dg/lookup/strong-using2.C: Likewise.
* g++.dg/cpp0x/gen-attrs-58.C: Move alignas(int) before
using namespace.
* g++.dg/cpp0x/gen-attrs-59.C: Move alignas(X) before
using namespace, add tests for alignas before semicolon.
* g++.dg/cpp0x/gen-attrs-76.C: Remove xfails. Add test for
C++11 attributes on using directive before semicolon.
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/parser.c | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index d564e3b..ec885d7 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -14853,6 +14853,7 @@ cp_parser_block_declaration (cp_parser *parser, /* Peek at the next token to figure out which kind of declaration is present. */ cp_token *token1 = cp_lexer_peek_token (parser->lexer); + size_t attr_idx; /* If the next keyword is `asm', we have an asm-definition. */ if (token1->keyword == RID_ASM) @@ -14906,6 +14907,18 @@ cp_parser_block_declaration (cp_parser *parser, /* If the next token is `static_assert' we have a static assertion. */ else if (token1->keyword == RID_STATIC_ASSERT) cp_parser_static_assert (parser, /*member_p=*/false); + /* If the next tokens after attributes is `using namespace', then we have + a using-directive. */ + else if ((attr_idx = cp_parser_skip_std_attribute_spec_seq (parser, 1)) != 1 + && cp_lexer_nth_token_is_keyword (parser->lexer, attr_idx, + RID_USING) + && cp_lexer_nth_token_is_keyword (parser->lexer, attr_idx + 1, + RID_NAMESPACE)) + { + if (statement_p) + cp_parser_commit_to_tentative_parse (parser); + cp_parser_using_directive (parser); + } /* Anything else must be a simple-declaration. */ else cp_parser_simple_declaration (parser, !statement_p, @@ -21609,14 +21622,21 @@ cp_parser_alias_declaration (cp_parser* parser) /* Parse a using-directive. using-directive: - using namespace :: [opt] nested-name-specifier [opt] - namespace-name ; */ + attribute-specifier-seq [opt] using namespace :: [opt] + nested-name-specifier [opt] namespace-name ; */ static void cp_parser_using_directive (cp_parser* parser) { tree namespace_decl; - tree attribs; + tree attribs = cp_parser_std_attribute_spec_seq (parser); + if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)) + { + /* Error during attribute parsing that resulted in skipping + to next semicolon. */ + cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); + return; + } /* Look for the `using' keyword. */ cp_parser_require_keyword (parser, RID_USING, RT_USING); @@ -21633,8 +21653,9 @@ cp_parser_using_directive (cp_parser* parser) /* Get the namespace being used. */ namespace_decl = cp_parser_namespace_name (parser); cp_warn_deprecated_use_scopes (namespace_decl); - /* And any specified attributes. */ - attribs = cp_parser_attributes_opt (parser); + /* And any specified GNU attributes. */ + if (cp_next_tokens_can_be_gnu_attribute_p (parser)) + attribs = chainon (attribs, cp_parser_gnu_attributes_opt (parser)); /* Update the symbol table. */ finish_using_directive (namespace_decl, attribs); |