llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-libcxx Author: Mark de Wever (mordante) <details> <summary>Changes</summary> Guards against introducing new places where operator& depends on a template type. --- Full diff: https://github.com/llvm/llvm-project/pull/128366.diff 4 Files Affected: - (modified) libcxx/test/tools/clang_tidy_checks/CMakeLists.txt (+1) - (modified) libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp (+3) - (added) libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.cpp (+44) - (added) libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.hpp (+18) ``````````diff diff --git a/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt b/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt index 0f8f0e8864d0f..e8e62c3f4ba40 100644 --- a/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt +++ b/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt @@ -96,6 +96,7 @@ set(SOURCES proper_version_checks.cpp qualify_declval.cpp robust_against_adl.cpp + robust_against_operator_ampersand.cpp uglify_attributes.cpp libcpp_module.cpp diff --git a/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp b/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp index bc7c8ce7ec443..a52e25f2cf08f 100644 --- a/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp +++ b/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp @@ -17,6 +17,7 @@ #include "proper_version_checks.hpp" #include "qualify_declval.hpp" #include "robust_against_adl.hpp" +#include "robust_against_operator_ampersand.hpp" #include "uglify_attributes.hpp" namespace { @@ -30,6 +31,8 @@ class LibcxxTestModule : public clang::tidy::ClangTidyModule { check_factories.registerCheck<libcpp::nodebug_on_aliases>("libcpp-nodebug-on-aliases"); check_factories.registerCheck<libcpp::proper_version_checks>("libcpp-cpp-version-check"); check_factories.registerCheck<libcpp::robust_against_adl_check>("libcpp-robust-against-adl"); + check_factories.registerCheck<libcpp::robust_against_operator_ampersand>( + "libcpp-robust-against-operator-ampersand"); check_factories.registerCheck<libcpp::uglify_attributes>("libcpp-uglify-attributes"); check_factories.registerCheck<libcpp::qualify_declval>("libcpp-qualify-declval"); } diff --git a/libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.cpp b/libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.cpp new file mode 100644 index 0000000000000..8361e0c3eee88 --- /dev/null +++ b/libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "clang-tidy/ClangTidyCheck.h" +#include "clang-tidy/ClangTidyModuleRegistry.h" +#include "clang/Tooling/FixIt.h" + +#include "robust_against_operator_ampersand.hpp" + +// This clang-tidy check ensures that we don't use operator& on dependant +// types. If the type is user supplied it may call the type's operator&. +// Instead use std::addressof. + +namespace libcpp { +robust_against_operator_ampersand::robust_against_operator_ampersand( + llvm::StringRef name, clang::tidy::ClangTidyContext* context) + : clang::tidy::ClangTidyCheck(name, context) {} + +void robust_against_operator_ampersand::registerMatchers(clang::ast_matchers::MatchFinder* finder) { + using namespace clang::ast_matchers; + finder->addMatcher( + cxxOperatorCallExpr(allOf(hasOperatorName("&"), argumentCountIs(1), isTypeDependent()), + unless(hasUnaryOperand(dependentScopeDeclRefExpr()))) + .bind("match"), + this); +} + +void robust_against_operator_ampersand::check(const clang::ast_matchers::MatchFinder::MatchResult& result) { + if (const auto* call = result.Nodes.getNodeAs< clang::CXXOperatorCallExpr >("match"); call != nullptr) { + diag(call->getBeginLoc(), "Guard against user provided operator& for dependent types.") + << clang::FixItHint::CreateReplacement( + call->getSourceRange(), + (llvm::Twine( + "std::addressof(" + clang::tooling::fixit::getText(*call->getArg(0), *result.Context) + ")")) + .str()); + } +} + +} // namespace libcpp diff --git a/libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.hpp b/libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.hpp new file mode 100644 index 0000000000000..5cdc0baca5c23 --- /dev/null +++ b/libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.hpp @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "clang-tidy/ClangTidyCheck.h" + +namespace libcpp { +class robust_against_operator_ampersand : public clang::tidy::ClangTidyCheck { +public: + robust_against_operator_ampersand(llvm::StringRef, clang::tidy::ClangTidyContext*); + void registerMatchers(clang::ast_matchers::MatchFinder*) override; + void check(const clang::ast_matchers::MatchFinder::MatchResult&) override; +}; +} // namespace libcpp `````````` </details> https://github.com/llvm/llvm-project/pull/128366 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits