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.
(cherry picked from commit
3890c28ac5bd03ba334a20fbf9518a37dcdbfe5d)
+2021-09-23 Tobias Burnus <tobias@codesourcery.com>
+
+ Backported from master:
+ 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.
+
2021-09-22 Tobias Burnus <tobias@codesourcery.com>
Backported from master:
/* 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)
/* 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,
/* 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);
/* 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);
+2021-09-23 Tobias Burnus <tobias@codesourcery.com>
+
+ Backported from master:
+ 2021-08-12 Jakub Jelinek <jakub@redhat.com>
+
+ * 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.
+
2021-09-22 Sandra Loosemore <sandra@codesourcery.com>
Backported from master:
// { dg-do compile { target c++11 } }
namespace N { int i; }
-using namespace N alignas(int); // { dg-warning "ignored" }
+alignas(int) using namespace N; // { dg-warning "ignored" }
// { dg-do compile { target c++11 } }
namespace N {}
-using namespace N alignas(X); // { dg-error "declared" }
+alignas(X) using namespace N; // { dg-error "declared" }
+namespace O {}
+using namespace O alignas(X); // { dg-error "expected" }
+// { dg-error "declared" "" { target *-*-* } .-1 }
+// { dg-warning "attribute ignored" "" { target *-*-* } .-2 }
+namespace P {}
+using namespace P alignas(int); // { dg-error "expected" }
+// { dg-warning "attribute ignored" "" { target *-*-* } .-1 }
namespace N {}
namespace O { typedef int T; };
+namespace P {}
void
foo ()
[[]] __extension__ asm (""); // { dg-error "expected" }
__extension__ [[]] asm (""); // { dg-error "expected" }
[[]] namespace M = ::N; // { dg-error "expected" }
- [[]] using namespace N; // { dg-bogus "expected" "" { xfail *-*-* } }
+ [[]] using namespace N; // { dg-bogus "expected" }
+ using namespace P [[]]; // { dg-error "expected" }
[[]] using O::T; // { dg-error "expected" }
[[]] __label__ foo; // { dg-error "expected" }
[[]] static_assert (true, ""); // { 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 namespace N; // { dg-bogus "expected" }
+ using namespace P [[gnu::unused]]; // { dg-error "expected" }
[[gnu::unused]] using O::T; // { dg-error "expected" }
[[gnu::unused]] __label__ foo; // { dg-error "expected" }
[[gnu::unused]] static_assert (true, ""); // { dg-error "expected" }
using namespace B __attribute__ ((strong)); // { dg-warning "no longer supported" "" }
}
+
+namespace C
+{
+ namespace D // { dg-message "inline namespace" }
+ {
+ }
+
+ [[gnu::strong]] using namespace D; // { dg-warning "no longer supported" "" }
+}
using namespace B __attribute__ ((strong)); // { dg-bogus "no longer supported" }
}
+
+namespace C
+{
+ namespace D // { dg-bogus "inline namespace" }
+ {
+ }
+
+ [[gnu::strong]] using namespace D; // { dg-bogus "no longer supported" }
+}