public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-2871] c++: Fix up parsing of attributes for using-directive
@ 2021-08-12  7:34 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2021-08-12  7:34 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:3890c28ac5bd03ba334a20fbf9518a37dcdbfe5d

commit r12-2871-g3890c28ac5bd03ba334a20fbf9518a37dcdbfe5d
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Thu Aug 12 09:09:39 2021 +0200

    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.

Diff:
---
 gcc/cp/parser.c                             | 31 ++++++++++++++++++++++++-----
 gcc/testsuite/g++.dg/cpp0x/gen-attrs-58.C   |  2 +-
 gcc/testsuite/g++.dg/cpp0x/gen-attrs-59.C   |  9 ++++++++-
 gcc/testsuite/g++.dg/cpp0x/gen-attrs-76.C   |  7 +++++--
 gcc/testsuite/g++.dg/lookup/strong-using.C  |  9 +++++++++
 gcc/testsuite/g++.dg/lookup/strong-using2.C |  9 +++++++++
 6 files changed, 58 insertions(+), 9 deletions(-)

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index d564e3ba2fa..ec885d774f2 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);
diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-58.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-58.C
index f760f560828..dc01722062a 100644
--- a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-58.C
+++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-58.C
@@ -2,4 +2,4 @@
 // { 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" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-59.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-59.C
index c7839fefed9..9776dc33745 100644
--- a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-59.C
+++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-59.C
@@ -2,4 +2,11 @@
 // { 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 }
diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-76.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-76.C
index cbda8de327e..72cd4b33e93 100644
--- a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-76.C
+++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-76.C
@@ -3,6 +3,7 @@
 
 namespace N {}
 namespace O { typedef int T; };
+namespace P {}
 
 void
 foo ()
@@ -11,7 +12,8 @@ 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" }
@@ -24,7 +26,8 @@ bar ()
   [[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" }
diff --git a/gcc/testsuite/g++.dg/lookup/strong-using.C b/gcc/testsuite/g++.dg/lookup/strong-using.C
index 9d58fddbb8f..2bd821ea219 100644
--- a/gcc/testsuite/g++.dg/lookup/strong-using.C
+++ b/gcc/testsuite/g++.dg/lookup/strong-using.C
@@ -8,3 +8,12 @@ namespace A
 
   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" "" }
+}
diff --git a/gcc/testsuite/g++.dg/lookup/strong-using2.C b/gcc/testsuite/g++.dg/lookup/strong-using2.C
index 17284949645..989827cacd3 100644
--- a/gcc/testsuite/g++.dg/lookup/strong-using2.C
+++ b/gcc/testsuite/g++.dg/lookup/strong-using2.C
@@ -9,3 +9,12 @@ namespace A
 
   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" }
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-08-12  7:34 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-12  7:34 [gcc r12-2871] c++: Fix up parsing of attributes for using-directive Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).