CJ-Johnson created this revision.
CJ-Johnson added a reviewer: ymandel.
Herald added subscribers: carlosgalvezp, mgorny.
CJ-Johnson requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.
Suggests switching the initialization pattern of absl::Cleanup instances from
the factory function to class template argument deduction (CTAD) in C++17 and
higher.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D113195
Files:
clang-tools-extra/clang-tidy/abseil/AbseilTidyModule.cpp
clang-tools-extra/clang-tidy/abseil/CMakeLists.txt
clang-tools-extra/clang-tidy/abseil/CleanupCtadCheck.cpp
clang-tools-extra/clang-tidy/abseil/CleanupCtadCheck.h
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/docs/clang-tidy/checks/abseil-cleanup-ctad.rst
clang-tools-extra/docs/clang-tidy/checks/list.rst
clang-tools-extra/test/clang-tidy/checkers/abseil-cleanup-ctad.cpp
Index: clang-tools-extra/test/clang-tidy/checkers/abseil-cleanup-ctad.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/abseil-cleanup-ctad.cpp
@@ -0,0 +1,68 @@
+// RUN: %check_clang_tidy %s abseil-cleanup-ctad -std=c++17 %t
+
+namespace absl {
+
+struct Tag {};
+
+template <typename, typename T>
+class Cleanup {
+public:
+ Cleanup(T) {}
+ Cleanup(Cleanup &&) {}
+};
+
+template <typename Callback>
+Cleanup(Callback callback) -> Cleanup<Tag, Callback>;
+
+template <typename T>
+absl::Cleanup<Tag, T> MakeCleanup(T t) {
+ return absl::Cleanup<Tag, T>(t);
+}
+
+} // namespace absl
+
+namespace std {
+
+template <typename>
+class function {
+public:
+ template <typename T>
+ function(T) {}
+ function(const function &) {}
+};
+
+} // namespace std
+
+void test() {
+ auto a = absl::MakeCleanup([] {});
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer absl::Cleanup's class template argument deduction pattern in C++17 and higher
+ // CHECK-FIXES: {{^}} absl::Cleanup a = [] {};{{$}}
+
+ auto b = absl::MakeCleanup(([] {}));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer absl::Cleanup's class template argument deduction pattern in C++17 and higher
+ // CHECK-FIXES: {{^}} absl::Cleanup b = [] {};{{$}}
+
+ const auto c = absl::MakeCleanup([] {});
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: prefer absl::Cleanup's class template argument deduction pattern in C++17 and higher
+ // CHECK-FIXES: {{^}} const absl::Cleanup c = [] {};{{$}}
+
+ const auto d = absl::MakeCleanup(([] {}));
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: prefer absl::Cleanup's class template argument deduction pattern in C++17 and higher
+ // CHECK-FIXES: {{^}} const absl::Cleanup d = [] {};{{$}}
+
+ auto e = absl::MakeCleanup(std::function<void()>([] {}));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer absl::Cleanup's class template argument deduction pattern in C++17 and higher
+ // CHECK-FIXES: {{^}} absl::Cleanup e = std::function<void()>([] {});{{$}}
+
+ auto f = absl::MakeCleanup((std::function<void()>([] {})));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer absl::Cleanup's class template argument deduction pattern in C++17 and higher
+ // CHECK-FIXES: {{^}} absl::Cleanup f = std::function<void()>([] {});{{$}}
+
+ const auto g = absl::MakeCleanup(std::function<void()>([] {}));
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: prefer absl::Cleanup's class template argument deduction pattern in C++17 and higher
+ // CHECK-FIXES: {{^}} const absl::Cleanup g = std::function<void()>([] {});{{$}}
+
+ const auto h = absl::MakeCleanup((std::function<void()>([] {})));
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: prefer absl::Cleanup's class template argument deduction pattern in C++17 and higher
+ // CHECK-FIXES: {{^}} const absl::Cleanup h = std::function<void()>([] {});{{$}}
+}
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===================================================================
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -12,6 +12,7 @@
.. csv-table::
:header: "Name", "Offers fixes"
+ `abseil-cleanup-ctad <abseil-cleanup-ctad.html>`_, "Yes"
`abseil-duration-addition <abseil-duration-addition.html>`_, "Yes"
`abseil-duration-comparison <abseil-duration-comparison.html>`_, "Yes"
`abseil-duration-conversion-cast <abseil-duration-conversion-cast.html>`_, "Yes"
@@ -114,13 +115,12 @@
`cert-dcl50-cpp <cert-dcl50-cpp.html>`_,
`cert-dcl58-cpp <cert-dcl58-cpp.html>`_,
`cert-env33-c <cert-env33-c.html>`_,
+ `cert-err33-c <cert-err33-c.html>`_,
`cert-err34-c <cert-err34-c.html>`_,
`cert-err52-cpp <cert-err52-cpp.html>`_,
`cert-err58-cpp <cert-err58-cpp.html>`_,
`cert-err60-cpp <cert-err60-cpp.html>`_,
- `cert-exp42-c <cert-exp42-c.html>`_,
`cert-flp30-c <cert-flp30-c.html>`_,
- `cert-flp37-c <cert-flp37-c.html>`_,
`cert-mem57-cpp <cert-mem57-cpp.html>`_,
`cert-msc50-cpp <cert-msc50-cpp.html>`_,
`cert-msc51-cpp <cert-msc51-cpp.html>`_,
@@ -288,6 +288,7 @@
`readability-const-return-type <readability-const-return-type.html>`_, "Yes"
`readability-container-size-empty <readability-container-size-empty.html>`_, "Yes"
`readability-convert-member-functions-to-static <readability-convert-member-functions-to-static.html>`_,
+ `readability-data-pointer <readability-data-pointer.html>`_,
`readability-delete-null-pointer <readability-delete-null-pointer.html>`_, "Yes"
`readability-else-after-return <readability-else-after-return.html>`_, "Yes"
`readability-function-cognitive-complexity <readability-function-cognitive-complexity.html>`_,
@@ -333,13 +334,14 @@
`cert-dcl03-c <cert-dcl03-c.html>`_, `misc-static-assert <misc-static-assert.html>`_, "Yes"
`cert-dcl16-c <cert-dcl16-c.html>`_, `readability-uppercase-literal-suffix <readability-uppercase-literal-suffix.html>`_, "Yes"
`cert-dcl37-c <cert-dcl37-c.html>`_, `bugprone-reserved-identifier <bugprone-reserved-identifier.html>`_, "Yes"
- `cert-err33-c <cert-err33-c.html>`_, `bugprone-unused-return-value <bugprone-unused-return-value.html>`_,
`cert-dcl51-cpp <cert-dcl51-cpp.html>`_, `bugprone-reserved-identifier <bugprone-reserved-identifier.html>`_, "Yes"
`cert-dcl54-cpp <cert-dcl54-cpp.html>`_, `misc-new-delete-overloads <misc-new-delete-overloads.html>`_,
`cert-dcl59-cpp <cert-dcl59-cpp.html>`_, `google-build-namespaces <google-build-namespaces.html>`_,
`cert-err09-cpp <cert-err09-cpp.html>`_, `misc-throw-by-value-catch-by-reference <misc-throw-by-value-catch-by-reference.html>`_,
`cert-err61-cpp <cert-err61-cpp.html>`_, `misc-throw-by-value-catch-by-reference <misc-throw-by-value-catch-by-reference.html>`_,
+ `cert-exp42-c <cert-exp42-c.html>`_, `bugprone-suspicious-memory-comparison <bugprone-suspicious-memory-comparison.html>`_,
`cert-fio38-c <cert-fio38-c.html>`_, `misc-non-copyable-objects <misc-non-copyable-objects.html>`_,
+ `cert-flp37-c <cert-flp37-c.html>`_, `bugprone-suspicious-memory-comparison <bugprone-suspicious-memory-comparison.html>`_,
`cert-msc30-c <cert-msc30-c.html>`_, `cert-msc50-cpp <cert-msc50-cpp.html>`_,
`cert-msc32-c <cert-msc32-c.html>`_, `cert-msc51-cpp <cert-msc51-cpp.html>`_,
`cert-oop11-cpp <cert-oop11-cpp.html>`_, `performance-move-constructor-init <performance-move-constructor-init.html>`_,
Index: clang-tools-extra/docs/clang-tidy/checks/abseil-cleanup-ctad.rst
===================================================================
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/abseil-cleanup-ctad.rst
@@ -0,0 +1,22 @@
+.. title:: clang-tidy - abseil-cleanup-ctad
+
+abseil-cleanup-ctad
+===================
+
+Suggests switching the initialization pattern of ``absl::Cleanup``
+instances from the factory function to class template argument
+deduction (CTAD) in C++17 and higher.
+
+.. code-block:: c++
+
+ auto c1 = absl::MakeCleanup([] {});
+
+ const auto c2 = absl::MakeCleanup(std::function<void()>([] {}));
+
+becomes
+
+.. code-block:: c++
+
+ absl::Cleanup c1 = [] {};
+
+ const absl::Cleanup c2 = std::function<void()>([] {});
Index: clang-tools-extra/docs/ReleaseNotes.rst
===================================================================
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -76,6 +76,13 @@
New checks
^^^^^^^^^^
+- New :doc:`abseil-cleanup-ctad
+ <clang-tidy/checks/abseil-cleanup-ctad>` check.
+
+ Suggests switching the initialization pattern of ``absl::Cleanup``
+ instances from the factory function to class template argument
+ deduction (CTAD) in C++17 and higher.
+
- New :doc:`bugprone-suspicious-memory-comparison
<clang-tidy/checks/bugprone-suspicious-memory-comparison>` check.
Index: clang-tools-extra/clang-tidy/abseil/CleanupCtadCheck.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/abseil/CleanupCtadCheck.h
@@ -0,0 +1,34 @@
+//===--- CleanupCtadCheck.h - clang-tidy ------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_CLEANUPCTADCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_CLEANUPCTADCHECK_H
+
+#include "../utils/TransformerClangTidyCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace abseil {
+
+/// Suggests switching the initialization pattern of `absl::Cleanup`
+/// instances from the factory function to class template argument
+/// deduction (CTAD) in C++17 and higher.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/abseil-cleanup-ctad.html
+class CleanupCtadCheck : public utils::TransformerClangTidyCheck {
+public:
+ CleanupCtadCheck(StringRef Name, ClangTidyContext *Context);
+ bool isLanguageVersionSupported(const LangOptions &LangOpts) const override;
+};
+
+} // namespace abseil
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_CLEANUPCTADCHECK_H
Index: clang-tools-extra/clang-tidy/abseil/CleanupCtadCheck.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/abseil/CleanupCtadCheck.cpp
@@ -0,0 +1,53 @@
+//===--- CleanupCtadCheck.cpp - clang-tidy --------------------------------===//
+//
+// 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 "CleanupCtadCheck.h"
+#include "../utils/TransformerClangTidyCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Transformer/RangeSelector.h"
+#include "clang/Tooling/Transformer/RewriteRule.h"
+#include "clang/Tooling/Transformer/Stencil.h"
+#include "llvm/ADT/StringRef.h"
+
+using namespace clang::ast_matchers;
+using namespace ::clang::transformer;
+
+namespace clang {
+namespace tidy {
+namespace abseil {
+
+RewriteRule CleanupCtadCheckImpl() {
+ auto warning_message = cat("prefer absl::Cleanup's class template argument "
+ "deduction pattern in C++17 and higher");
+
+ return makeRule(
+ declStmt(has(varDecl(
+ hasType(autoType()), hasTypeLoc(typeLoc().bind("auto_typeLoc")),
+ hasInitializer(ignoringImpCasts(
+ callExpr(callee(functionDecl(hasName("absl::MakeCleanup"))),
+ argumentCountIs(1),
+ hasArgument(0, expr().bind("make_cleanup_argument")))
+ .bind("make_cleanup_call")))))),
+ {changeTo(node("auto_typeLoc"), cat("absl::Cleanup")),
+ changeTo(node("make_cleanup_call"), cat(node("make_cleanup_argument")))},
+ warning_message);
+}
+
+CleanupCtadCheck::CleanupCtadCheck(StringRef Name, ClangTidyContext *Context)
+ : utils::TransformerClangTidyCheck(CleanupCtadCheckImpl(), Name, Context) {}
+
+bool CleanupCtadCheck::isLanguageVersionSupported(
+ const LangOptions &LangOpts) const {
+ return LangOpts.CPlusPlus17;
+}
+
+} // namespace abseil
+} // namespace tidy
+} // namespace clang
Index: clang-tools-extra/clang-tidy/abseil/CMakeLists.txt
===================================================================
--- clang-tools-extra/clang-tidy/abseil/CMakeLists.txt
+++ clang-tools-extra/clang-tidy/abseil/CMakeLists.txt
@@ -5,6 +5,7 @@
add_clang_library(clangTidyAbseilModule
AbseilTidyModule.cpp
+ CleanupCtadCheck.cpp
DurationAdditionCheck.cpp
DurationComparisonCheck.cpp
DurationConversionCastCheck.cpp
Index: clang-tools-extra/clang-tidy/abseil/AbseilTidyModule.cpp
===================================================================
--- clang-tools-extra/clang-tidy/abseil/AbseilTidyModule.cpp
+++ clang-tools-extra/clang-tidy/abseil/AbseilTidyModule.cpp
@@ -9,6 +9,7 @@
#include "../ClangTidy.h"
#include "../ClangTidyModule.h"
#include "../ClangTidyModuleRegistry.h"
+#include "CleanupCtadCheck.h"
#include "DurationAdditionCheck.h"
#include "DurationComparisonCheck.h"
#include "DurationConversionCastCheck.h"
@@ -35,6 +36,7 @@
class AbseilModule : public ClangTidyModule {
public:
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
+ CheckFactories.registerCheck<CleanupCtadCheck>("abseil-cleanup-ctad");
CheckFactories.registerCheck<DurationAdditionCheck>(
"abseil-duration-addition");
CheckFactories.registerCheck<DurationComparisonCheck>(
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits