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 @@ -75,6 +75,17 @@ ParsedAttributesWithRange attrs(AttrFactory); SourceLocation attrLoc; + + auto ReadLabelAttrubutes = [&] { + // Read label attributes, if present. + if (Tok.is(tok::kw___attribute)) { + attrLoc = Tok.getLocation(); + ParseGNUAttributes(attrs); + } + }; + + ReadLabelAttrubutes(); + if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) { Diag(Tok.getLocation(), getLangOpts().CPlusPlus17 ? diag::warn_cxx14_compat_ns_enum_attribute @@ -108,16 +119,12 @@ } } + ReadLabelAttrubutes(); + // 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,17 @@ +// RUN: %clang_cc1 -std=c++17 -verify %s + +namespace __attribute__((visibility("hidden"))) A +{ +} + +namespace B __attribute__((visibility("hidden"))) +{ +} + +namespace C::D __attribute__((visibility("hidden"))) // expected-error{{attributes cannot be specified on a nested namespace definition}} +{ +} + +namespace __attribute__((visibility("hidden"))) E::F // expected-error{{attributes cannot be specified on a nested namespace definition}} +{ +}