diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -94,6 +94,11 @@
   locations a declaration attribute may appear.
   This fixes `Issue 53805 <https://github.com/llvm/llvm-project/issues/53805>`_.
 
+- Improved namespace attributes handling:
+  - Handle GNU attributes before a namespace identifier and subsequent
+    attributes of different kinds.
+  - Emit error on GNU attributes for a nested namespace definition.
+
 Windows Support
 ---------------
 
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -74,15 +74,27 @@
   SourceLocation FirstNestedInlineLoc;
 
   ParsedAttributesWithRange attrs(AttrFactory);
-  SourceLocation attrLoc;
-  if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) {
-    Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
-                                ? diag::warn_cxx14_compat_ns_enum_attribute
-                                : diag::ext_ns_enum_attribute)
-      << 0 /*namespace*/;
-    attrLoc = Tok.getLocation();
-    ParseCXX11Attributes(attrs);
-  }
+
+  auto ReadAttributes = [&] {
+    bool MoreToParse;
+    do {
+      MoreToParse = false;
+      if (Tok.is(tok::kw___attribute)) {
+        ParseGNUAttributes(attrs);
+        MoreToParse = true;
+      }
+      if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) {
+        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();
 
   if (Tok.is(tok::identifier)) {
     Ident = Tok.getIdentifierInfo();
@@ -108,16 +120,14 @@
     }
   }
 
+  ReadAttributes();
+
+  SourceLocation attrLoc = attrs.Range.getBegin();
+
   // A nested namespace definition cannot have attributes.
   if (!ExtraNSs.empty() && attrLoc.isValid())
     Diag(attrLoc, diag::err_unexpected_nested_namespace_attribute);
 
-  // Read label attributes, if present.
-  if (Tok.is(tok::kw___attribute)) {
-    attrLoc = Tok.getLocation();
-    ParseGNUAttributes(attrs);
-  }
-
   if (Tok.is(tok::equal)) {
     if (!Ident) {
       Diag(Tok, diag::err_expected) << tok::identifier;
diff --git a/clang/test/Parser/namespace-attributes.cpp b/clang/test/Parser/namespace-attributes.cpp
new file mode 100644
--- /dev/null
+++ b/clang/test/Parser/namespace-attributes.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -std=c++17 -verify %s
+
+namespace __attribute__(()) A
+{
+}
+
+namespace A __attribute__(())
+{
+}
+
+namespace __attribute__(()) [[]] A
+{
+}
+
+namespace [[]] __attribute__(()) A
+{
+}
+
+namespace A __attribute__(()) [[]]
+{
+}
+
+namespace A [[]] __attribute__(())
+{
+}
+
+namespace [[]] A __attribute__(())
+{
+}
+
+namespace __attribute__(()) A [[]]
+{
+}
+
+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}}
+{
+}