[llvm-branch-commits] [libcxx] [libc++] Clang-tidy operator& hijacker. (PR #128366)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sat Feb 22 09:45:05 PST 2025
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
More information about the llvm-branch-commits
mailing list