diff --git a/libcxx/include/__config b/libcxx/include/__config --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -869,7 +869,7 @@ # endif # if __has_cpp_attribute(nodiscard) -# define _LIBCPP_NODISCARD [[nodiscard]] +# define _LIBCPP_NODISCARD [[__nodiscard__]] # else // We can't use GCC's [[gnu::warn_unused_result]] and // __attribute__((warn_unused_result)), because GCC does not silence them via @@ -1188,7 +1188,7 @@ // [[msvc::no_unique_address]], this should be preferred though. # define _LIBCPP_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]] # elif __has_cpp_attribute(no_unique_address) -# define _LIBCPP_NO_UNIQUE_ADDRESS [[no_unique_address]] +# define _LIBCPP_NO_UNIQUE_ADDRESS [[__no_unique_address__]] # else # define _LIBCPP_NO_UNIQUE_ADDRESS /* nothing */ // Note that this can be replaced by #error as soon as clang-cl diff --git a/libcxx/include/barrier b/libcxx/include/barrier --- a/libcxx/include/barrier +++ b/libcxx/include/barrier @@ -130,7 +130,7 @@ __expected_adjustment_(0), __completion_(std::move(__completion)), __phase_(0) { } - [[nodiscard]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + [[__nodiscard__]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY arrival_token arrive(ptrdiff_t __update) { auto const __old_phase = __phase_.load(memory_order_relaxed); @@ -300,7 +300,7 @@ barrier(barrier const&) = delete; barrier& operator=(barrier const&) = delete; - [[nodiscard]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + [[__nodiscard__]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY arrival_token arrive(ptrdiff_t __update = 1) { return __b_.arrive(__update); diff --git a/libcxx/test/tools/clang_tidy_checks/uglify_attributes.cpp b/libcxx/test/tools/clang_tidy_checks/uglify_attributes.cpp --- a/libcxx/test/tools/clang_tidy_checks/uglify_attributes.cpp +++ b/libcxx/test/tools/clang_tidy_checks/uglify_attributes.cpp @@ -12,6 +12,8 @@ #include "uglify_attributes.hpp" #include +#include +#include #include namespace { @@ -23,15 +25,57 @@ return str.find("__") != std::string_view::npos; } +const std::array standard_attributes = { + // C++11 attributes + "noreturn", + "carries_dependency", + + // C++14 attributes + "deprecated", + + // C++17 attributes + "fallthrough", + "nodiscard", + "maybe_unused", + + // C++20 attributes + "likely", + "unlikely", + "no_unique_address", + + // C++23 attributes + "assume"}; + +std::span get_standard_attributes(const clang::LangOptions& lang_opts) { + size_t attribute_count = 2; + + if (lang_opts.CPlusPlus14) + attribute_count += 1; + + if (lang_opts.CPlusPlus17) + attribute_count += 3; + + if (lang_opts.CPlusPlus20) + attribute_count += 3; + + if (lang_opts.CPlusPlus2b) + attribute_count += 1; + + return {standard_attributes.begin(), standard_attributes.begin() + attribute_count}; +} + AST_MATCHER(clang::Attr, isPretty) { if (Node.isKeywordAttribute()) return false; - if (Node.isCXX11Attribute() && !Node.hasScope()) // TODO: reject standard attributes that are version extensions - return false; + if (Node.isCXX11Attribute() && !Node.hasScope()) { + if (isUgly(Node.getAttrName()->getName())) + return false; + return !llvm::is_contained( + get_standard_attributes(Finder->getASTContext().getLangOpts()), Node.getAttrName()->getName()); + } if (Node.hasScope()) if (!isUgly(Node.getScopeName()->getName())) return true; - if (Node.getAttrName()) return !isUgly(Node.getAttrName()->getName()); @@ -39,9 +83,7 @@ } std::optional getUglyfiedCXX11Attr(const clang::Attr& attr) { - // Don't try to fix attributes with `using` in them. - if (std::ranges::search(std::string_view(attr.getSpelling()), std::string_view("::")).empty()) - return std::nullopt; + // TODO: Don't try to fix attributes with `using` in them. std::string attr_string; if (attr.isClangScope())