https://github.com/a-tarasyuk updated 
https://github.com/llvm/llvm-project/pull/121614

>From b8f6ffc0a98a0d3ac55fba4e6ee680f1edea4571 Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.taras...@outlook.com>
Date: Sat, 4 Jan 2025 02:24:26 +0200
Subject: [PATCH 1/4] [Clang] disallow attributes after namespace identifier

---
 clang/docs/ReleaseNotes.rst                       |  2 ++
 clang/include/clang/Basic/DiagnosticParseKinds.td |  2 ++
 clang/lib/Parse/ParseDeclCXX.cpp                  |  9 ++++++---
 clang/test/Parser/namespace-attributes.cpp        | 10 +++++-----
 4 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e0aef1af2135cd..43a95fd022c070 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -553,6 +553,8 @@ Attribute Changes in Clang
 - Clang now permits the usage of the placement new operator in 
``[[msvc::constexpr]]``
   context outside of the std namespace. (#GH74924)
 
+- Clang now disallows the use of attributes after the namespace name. 
(#GH121407)
+
 Improvements to Clang's diagnostics
 -----------------------------------
 
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 86fcae209c40db..9d76376cd6b015 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -283,6 +283,8 @@ def err_unexpected_qualified_namespace_alias : Error<
   "namespace alias must be a single identifier">;
 def err_unexpected_nested_namespace_attribute : Error<
   "attributes cannot be specified on a nested namespace definition">;
+def err_attribute_after_namespace : Error<
+  "standard attributes cannot appear after the namespace name">;
 def err_inline_namespace_alias : Error<"namespace alias cannot be inline">;
 def err_namespace_nonnamespace_scope : Error<
   "namespaces can only be defined in global or namespace scope">;
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index f30603feb65c5d..ec87163ffb7cee 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -81,7 +81,7 @@ Parser::DeclGroupPtrTy 
Parser::ParseNamespace(DeclaratorContext Context,
 
   ParsedAttributes attrs(AttrFactory);
 
-  auto ReadAttributes = [&] {
+  auto ReadAttributes = [&](bool TrailingAttrs) {
     bool MoreToParse;
     do {
       MoreToParse = false;
@@ -90,6 +90,9 @@ Parser::DeclGroupPtrTy 
Parser::ParseNamespace(DeclaratorContext Context,
         MoreToParse = true;
       }
       if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) {
+        if (TrailingAttrs)
+          Diag(Tok.getLocation(), diag::err_attribute_after_namespace);
+
         Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
                                     ? diag::warn_cxx14_compat_ns_enum_attribute
                                     : diag::ext_ns_enum_attribute)
@@ -100,7 +103,7 @@ Parser::DeclGroupPtrTy 
Parser::ParseNamespace(DeclaratorContext Context,
     } while (MoreToParse);
   };
 
-  ReadAttributes();
+  ReadAttributes(/*TrailingAttrs*/ false);
 
   if (Tok.is(tok::identifier)) {
     Ident = Tok.getIdentifierInfo();
@@ -126,7 +129,7 @@ Parser::DeclGroupPtrTy 
Parser::ParseNamespace(DeclaratorContext Context,
     }
   }
 
-  ReadAttributes();
+  ReadAttributes(/*TrailingAttrs*/ true);
 
   SourceLocation attrLoc = attrs.Range.getBegin();
 
diff --git a/clang/test/Parser/namespace-attributes.cpp 
b/clang/test/Parser/namespace-attributes.cpp
index 9f925b742dfebd..8a873c55c5d633 100644
--- a/clang/test/Parser/namespace-attributes.cpp
+++ b/clang/test/Parser/namespace-attributes.cpp
@@ -16,11 +16,11 @@ namespace [[]] __attribute__(()) A
 {
 }
 
-namespace A __attribute__(()) [[]]
+namespace A __attribute__(()) [[]] // expected-error {{standard attributes 
cannot appear after the namespace name}}
 {
 }
 
-namespace A [[]] __attribute__(())
+namespace A [[]] __attribute__(()) // expected-error {{standard attributes 
cannot appear after the namespace name}}
 {
 }
 
@@ -28,14 +28,14 @@ namespace [[]] A __attribute__(())
 {
 }
 
-namespace __attribute__(()) A [[]]
+namespace __attribute__(()) A [[]] // expected-error {{standard attributes 
cannot appear after the namespace name}}
 {
 }
 
-namespace A::B __attribute__(()) // expected-error{{attributes cannot be 
specified on a nested namespace definition}}
+namespace A::B __attribute__(()) // expected-error {{attributes cannot be 
specified on a nested namespace definition}}
 {
 }
 
-namespace __attribute__(()) A::B // expected-error{{attributes cannot be 
specified on a nested namespace definition}}
+namespace __attribute__(()) A::B // expected-error {{attributes cannot be 
specified on a nested namespace definition}}
 {
 }

>From b8bf77687644c035683ae64a0a2a8e788ad74a83 Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.taras...@outlook.com>
Date: Sun, 5 Jan 2025 12:07:40 +0200
Subject: [PATCH 2/4] change param name from TrailingAttrs to
 CheckProhibitedCXX11Attribute

---
 clang/lib/Parse/ParseDeclCXX.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index ec87163ffb7cee..7b810bb66138d3 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -81,7 +81,7 @@ Parser::DeclGroupPtrTy 
Parser::ParseNamespace(DeclaratorContext Context,
 
   ParsedAttributes attrs(AttrFactory);
 
-  auto ReadAttributes = [&](bool TrailingAttrs) {
+  auto ReadAttributes = [&](bool CheckProhibitedCXX11Attribute) {
     bool MoreToParse;
     do {
       MoreToParse = false;
@@ -90,7 +90,7 @@ Parser::DeclGroupPtrTy 
Parser::ParseNamespace(DeclaratorContext Context,
         MoreToParse = true;
       }
       if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) {
-        if (TrailingAttrs)
+        if (CheckProhibitedCXX11Attribute)
           Diag(Tok.getLocation(), diag::err_attribute_after_namespace);
 
         Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
@@ -103,7 +103,7 @@ Parser::DeclGroupPtrTy 
Parser::ParseNamespace(DeclaratorContext Context,
     } while (MoreToParse);
   };
 
-  ReadAttributes(/*TrailingAttrs*/ false);
+  ReadAttributes(/*CheckProhibitedCXX11Attribute*/ false);
 
   if (Tok.is(tok::identifier)) {
     Ident = Tok.getIdentifierInfo();
@@ -129,7 +129,7 @@ Parser::DeclGroupPtrTy 
Parser::ParseNamespace(DeclaratorContext Context,
     }
   }
 
-  ReadAttributes(/*TrailingAttrs*/ true);
+  ReadAttributes(/*CheckProhibitedCXX11Attribute*/ true);
 
   SourceLocation attrLoc = attrs.Range.getBegin();
 

>From c752a8af98f688557673e5b7b975cc6f2a669740 Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.taras...@outlook.com>
Date: Mon, 6 Jan 2025 00:20:04 +0200
Subject: [PATCH 3/4] refactor attributes handling to use existing helpers

---
 .../clang/Basic/DiagnosticParseKinds.td       |  2 --
 clang/lib/Parse/ParseDeclCXX.cpp              | 36 +++++++------------
 clang/test/Parser/namespace-attributes.cpp    | 21 +++--------
 3 files changed, 17 insertions(+), 42 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 9d76376cd6b015..86fcae209c40db 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -283,8 +283,6 @@ def err_unexpected_qualified_namespace_alias : Error<
   "namespace alias must be a single identifier">;
 def err_unexpected_nested_namespace_attribute : Error<
   "attributes cannot be specified on a nested namespace definition">;
-def err_attribute_after_namespace : Error<
-  "standard attributes cannot appear after the namespace name">;
 def err_inline_namespace_alias : Error<"namespace alias cannot be inline">;
 def err_namespace_nonnamespace_scope : Error<
   "namespaces can only be defined in global or namespace scope">;
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 7b810bb66138d3..7d4146d5c833fd 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -81,29 +81,15 @@ Parser::DeclGroupPtrTy 
Parser::ParseNamespace(DeclaratorContext Context,
 
   ParsedAttributes attrs(AttrFactory);
 
-  auto ReadAttributes = [&](bool CheckProhibitedCXX11Attribute) {
-    bool MoreToParse;
-    do {
-      MoreToParse = false;
-      if (Tok.is(tok::kw___attribute)) {
-        ParseGNUAttributes(attrs);
-        MoreToParse = true;
-      }
-      if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) {
-        if (CheckProhibitedCXX11Attribute)
-          Diag(Tok.getLocation(), diag::err_attribute_after_namespace);
-
-        Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
-                                    ? diag::warn_cxx14_compat_ns_enum_attribute
-                                    : diag::ext_ns_enum_attribute)
-            << 0 /*namespace*/;
-        ParseCXX11Attributes(attrs);
-        MoreToParse = true;
-      }
-    } while (MoreToParse);
-  };
-
-  ReadAttributes(/*CheckProhibitedCXX11Attribute*/ false);
+  MaybeParseGNUAttributes(attrs);
+  if (isAllowedCXX11AttributeSpecifier()) {
+    if (getLangOpts().CPlusPlus11)
+      Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
+                                  ? diag::warn_cxx14_compat_ns_enum_attribute
+                                  : diag::ext_ns_enum_attribute)
+          << 0 /*namespace*/;
+    ParseCXX11Attributes(attrs);
+  }
 
   if (Tok.is(tok::identifier)) {
     Ident = Tok.getIdentifierInfo();
@@ -129,7 +115,9 @@ Parser::DeclGroupPtrTy 
Parser::ParseNamespace(DeclaratorContext Context,
     }
   }
 
-  ReadAttributes(/*CheckProhibitedCXX11Attribute*/ true);
+  MaybeParseGNUAttributes(attrs);
+  if (Tok.is(tok::l_square))
+    CheckProhibitedCXX11Attribute();
 
   SourceLocation attrLoc = attrs.Range.getBegin();
 
diff --git a/clang/test/Parser/namespace-attributes.cpp 
b/clang/test/Parser/namespace-attributes.cpp
index 8a873c55c5d633..b199db2ed38810 100644
--- a/clang/test/Parser/namespace-attributes.cpp
+++ b/clang/test/Parser/namespace-attributes.cpp
@@ -4,31 +4,20 @@ namespace __attribute__(()) A
 {
 }
 
-namespace A __attribute__(())
+namespace A __attribute__(()) [[]] // expected-error {{an attribute list 
cannot appear here}}
 {
 }
 
-namespace __attribute__(()) [[]] A
-{
-}
-
-namespace [[]] __attribute__(()) A
-{
-}
-
-namespace A __attribute__(()) [[]] // expected-error {{standard attributes 
cannot appear after the namespace name}}
-{
-}
-
-namespace A [[]] __attribute__(()) // expected-error {{standard attributes 
cannot appear after the namespace name}}
-{
+namespace A [[]] __attribute__(()) // expected-error {{an attribute list 
cannot appear here}} \
+                                   // expected-error {{expected '{'}}
+{                                  // expected-error {{expected 
unqualified-id}}
 }
 
 namespace [[]] A __attribute__(())
 {
 }
 
-namespace __attribute__(()) A [[]] // expected-error {{standard attributes 
cannot appear after the namespace name}}
+namespace __attribute__(()) A [[]] // expected-error {{an attribute list 
cannot appear here}}
 {
 }
 

>From f5780f08194f157dd84723c00043e9894015c4c0 Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.taras...@outlook.com>
Date: Mon, 6 Jan 2025 00:46:56 +0200
Subject: [PATCH 4/4] handle GNU/CXX11 attributes before namespace name

---
 clang/lib/Parse/ParseDeclCXX.cpp           | 21 +++++++++++----------
 clang/test/Parser/namespace-attributes.cpp | 13 ++++++++++---
 2 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 7d4146d5c833fd..fddb8a5729ee8c 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -81,14 +81,15 @@ Parser::DeclGroupPtrTy 
Parser::ParseNamespace(DeclaratorContext Context,
 
   ParsedAttributes attrs(AttrFactory);
 
-  MaybeParseGNUAttributes(attrs);
-  if (isAllowedCXX11AttributeSpecifier()) {
-    if (getLangOpts().CPlusPlus11)
-      Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
-                                  ? diag::warn_cxx14_compat_ns_enum_attribute
-                                  : diag::ext_ns_enum_attribute)
-          << 0 /*namespace*/;
-    ParseCXX11Attributes(attrs);
+  while (MaybeParseGNUAttributes(attrs) || isAllowedCXX11AttributeSpecifier()) 
{
+    if (isAllowedCXX11AttributeSpecifier()) {
+      if (getLangOpts().CPlusPlus11)
+        Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
+                                    ? diag::warn_cxx14_compat_ns_enum_attribute
+                                    : diag::ext_ns_enum_attribute)
+            << 0 /*namespace*/;
+      ParseCXX11Attributes(attrs);
+    }
   }
 
   if (Tok.is(tok::identifier)) {
@@ -115,9 +116,9 @@ Parser::DeclGroupPtrTy 
Parser::ParseNamespace(DeclaratorContext Context,
     }
   }
 
+  DiagnoseAndSkipCXX11Attributes();
   MaybeParseGNUAttributes(attrs);
-  if (Tok.is(tok::l_square))
-    CheckProhibitedCXX11Attribute();
+  DiagnoseAndSkipCXX11Attributes();
 
   SourceLocation attrLoc = attrs.Range.getBegin();
 
diff --git a/clang/test/Parser/namespace-attributes.cpp 
b/clang/test/Parser/namespace-attributes.cpp
index b199db2ed38810..11bf8711cfad5d 100644
--- a/clang/test/Parser/namespace-attributes.cpp
+++ b/clang/test/Parser/namespace-attributes.cpp
@@ -8,15 +8,22 @@ namespace A __attribute__(()) [[]] // expected-error {{an 
attribute list cannot
 {
 }
 
-namespace A [[]] __attribute__(()) // expected-error {{an attribute list 
cannot appear here}} \
-                                   // expected-error {{expected '{'}}
-{                                  // expected-error {{expected 
unqualified-id}}
+namespace A [[]] __attribute__(()) // expected-error {{an attribute list 
cannot appear here}}
+{
 }
 
 namespace [[]] A __attribute__(())
 {
 }
 
+namespace [[]] __attribute__(()) A
+{
+}
+
+namespace __attribute__(()) [[]] A
+{
+}
+
 namespace __attribute__(()) A [[]] // expected-error {{an attribute list 
cannot appear here}}
 {
 }

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to