Blackhart updated this revision to Diff 205331.
Blackhart added a comment.
- Reorder release note changes
- Update documentation
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D63324/new/
https://reviews.llvm.org/D63324
Files:
clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
clang-tools-extra/clang-tidy/modernize/ReplaceMemcpyByStdCopy.cpp
clang-tools-extra/clang-tidy/modernize/ReplaceMemcpyByStdCopy.h
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/docs/clang-tidy/checks/list.rst
clang-tools-extra/docs/clang-tidy/checks/modernize-replace-memcpy-by-stdcopy.rst
Index: clang-tools-extra/docs/clang-tidy/checks/modernize-replace-memcpy-by-stdcopy.rst
===================================================================
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/modernize-replace-memcpy-by-stdcopy.rst
@@ -0,0 +1,47 @@
+.. title:: clang-tidy - modernize-replace-memcpy-by-stdcopy
+
+modernize-replace-memcpy-by-stdcopy
+===================================
+
+This check replaces all occurrences of the C ``memcpy`` function by ``std::copy``
+
+Example:
+
+.. code-block:: c++
+
+ /*!
+ * \param destination Pointer to the destination array where the content is to be copied
+ * \param source Pointer to the source of data to be copied
+ * \param num Number of bytes to copy
+ */
+ memcpy(destination, source, num);
+
+becomes
+
+.. code-block:: c++
+
+ /*!
+ * \param destination Pointer to the destination array where the content is to be copied
+ * \param source Pointer to the source of data to be copied
+ * \param num Number of bytes to copy
+ */
+ std::copy(source, source + (num / sizeof *source), destination);
+
+Bytes to iterator conversion
+----------------------------
+
+Unlike ``std::copy`` that take an iterator on the last element of the source array, ``memcpy`` request the number of bytes to copy.
+In order to make the check working, it will convert the size parameter to an iterator by replacing it by ``source + (num / sizeof *source)``
+
+Include
+-------
+
+``std::copy`` being provided by the ``algorithm`` include file, this check will include it if needed.
+
+Options
+-------
+
+.. option:: IncludeStyle
+
+ A string specifying which include-style is used, `llvm` or `google`. Default
+ is `llvm`.
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
@@ -211,6 +211,7 @@
modernize-raw-string-literal
modernize-redundant-void-arg
modernize-replace-auto-ptr
+ modernize-replace-memcpy-by-stdcopy
modernize-replace-random-shuffle
modernize-return-braced-init-list
modernize-shrink-to-fit
Index: clang-tools-extra/docs/ReleaseNotes.rst
===================================================================
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -186,6 +186,11 @@
finds and replaces cases that match the pattern ``var &&
isa<X>(var)``, where ``var`` is evaluated twice.
+- New :doc:`modernize-replace-memcpy-by-stdcopy
+ <clang-tidy/checks/modernize-replace-memcpy-by-stdcopy>` check.
+
+ This check replaces all occurrences of the C ``memcpy`` function by ``std::copy``.
+
- New :doc:`modernize-use-trailing-return-type
<clang-tidy/checks/modernize-use-trailing-return-type>` check.
Index: clang-tools-extra/clang-tidy/modernize/ReplaceMemcpyByStdCopy.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/modernize/ReplaceMemcpyByStdCopy.h
@@ -0,0 +1,48 @@
+//===--- ReplaceMemcpyByStdCopy.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_MODERNIZE_REPLACE_MEMCPY_BY_STDCOPY_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_REPLACE_MEMCPY_BY_STDCOPY_H
+
+#include "../ClangTidyCheck.h"
+#include "../utils/IncludeInserter.h"
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace tidy {
+namespace modernize {
+
+/// Replace the C memcpy function by std::copy
+class ReplaceMemcpyByStdCopy : public ClangTidyCheck {
+public:
+ ReplaceMemcpyByStdCopy(StringRef Name, ClangTidyContext *Context);
+ ~ReplaceMemcpyByStdCopy() override = default;
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+ Preprocessor *ModuleExpanderPP) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+ void storeOptions(ClangTidyOptions::OptionMap &Options) override;
+
+private:
+ void renameFunction(DiagnosticBuilder &Diag, const CallExpr *MemcpyNode);
+ void reorderArgs(DiagnosticBuilder &Diag, const CallExpr *MemcpyNode);
+ void insertHeader(DiagnosticBuilder &Diag, const CallExpr *MemcpyNode,
+ SourceManager *const SM);
+
+private:
+ std::unique_ptr<utils::IncludeInserter> Inserter;
+ const utils::IncludeSorter::IncludeStyle IncludeStyle;
+};
+
+} // namespace modernize
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_REPLACE_MEMCPY_BY_STDCOPY_H
Index: clang-tools-extra/clang-tidy/modernize/ReplaceMemcpyByStdCopy.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/modernize/ReplaceMemcpyByStdCopy.cpp
@@ -0,0 +1,117 @@
+//===--- ReplaceMemcpyByStdCopy.cpp - 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "ReplaceMemcpyByStdCopy.h"
+#include "../utils/OptionsUtils.h"
+#include <array>
+
+using namespace clang;
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace modernize {
+
+ReplaceMemcpyByStdCopy::ReplaceMemcpyByStdCopy(StringRef Name,
+ ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context),
+ IncludeStyle(utils::IncludeSorter::parseIncludeStyle(
+ Options.getLocalOrGlobal("IncludeStyle", "llvm"))) {}
+
+void ReplaceMemcpyByStdCopy::registerMatchers(MatchFinder *Finder) {
+ assert(Finder != nullptr);
+
+ if (!getLangOpts().CPlusPlus)
+ return;
+
+ auto MemcpyMatcher =
+ callExpr(hasDeclaration(functionDecl(hasName("memcpy"),
+ isExpansionInSystemHeader())),
+ isExpansionInMainFile())
+ .bind("memcpy_function");
+
+ Finder->addMatcher(MemcpyMatcher, this);
+}
+
+void ReplaceMemcpyByStdCopy::registerPPCallbacks(
+ const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
+ if (!getLangOpts().CPlusPlus)
+ return;
+
+ Inserter = llvm::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
+ IncludeStyle);
+ PP->addPPCallbacks(Inserter->CreatePPCallbacks());
+}
+
+void ReplaceMemcpyByStdCopy::check(const MatchFinder::MatchResult &Result) {
+ const auto *MemcpyNode = Result.Nodes.getNodeAs<CallExpr>("memcpy_function");
+ assert(MemcpyNode != nullptr);
+
+ DiagnosticBuilder Diag =
+ diag(MemcpyNode->getExprLoc(), "use std::copy instead of memcpy");
+
+ renameFunction(Diag, MemcpyNode);
+ reorderArgs(Diag, MemcpyNode);
+ insertHeader(Diag, MemcpyNode, Result.SourceManager);
+}
+
+void ReplaceMemcpyByStdCopy::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "IncludeStyle",
+ utils::IncludeSorter::toString(IncludeStyle));
+}
+
+void ReplaceMemcpyByStdCopy::renameFunction(DiagnosticBuilder &Diag,
+ const CallExpr *MemcpyNode) {
+ const CharSourceRange FunctionNameSourceRange = CharSourceRange::getCharRange(
+ MemcpyNode->getBeginLoc(), MemcpyNode->getArg(0)->getBeginLoc());
+
+ Diag << FixItHint::CreateReplacement(FunctionNameSourceRange, "std::copy(");
+}
+
+void ReplaceMemcpyByStdCopy::reorderArgs(DiagnosticBuilder &Diag,
+ const CallExpr *MemcpyNode) {
+ std::array<std::string, 3> arg;
+
+ LangOptions LangOpts;
+ LangOpts.CPlusPlus = true;
+ PrintingPolicy Policy(LangOpts);
+
+ // Retrieve all the arguments
+ for (uint8_t i = 0; i < arg.size(); i++) {
+ llvm::raw_string_ostream s(arg[i]);
+ MemcpyNode->getArg(i)->printPretty(s, nullptr, Policy);
+ }
+
+ // Create lambda that return SourceRange of an argument
+ auto getSourceRange = [MemcpyNode](uint8_t ArgCount) -> SourceRange {
+ return SourceRange(MemcpyNode->getArg(ArgCount)->getBeginLoc(),
+ MemcpyNode->getArg(ArgCount)->getEndLoc());
+ };
+
+ // Reorder the arguments
+ Diag << FixItHint::CreateReplacement(getSourceRange(0), arg[1]);
+
+ arg[2] = arg[1] + " + ((" + arg[2] + ") / sizeof(*(" + arg[1] + ")))";
+ Diag << FixItHint::CreateReplacement(getSourceRange(1), arg[2]);
+
+ Diag << FixItHint::CreateReplacement(getSourceRange(2), arg[0]);
+}
+
+void ReplaceMemcpyByStdCopy::insertHeader(DiagnosticBuilder &Diag,
+ const CallExpr *MemcpyNode,
+ SourceManager *const SM) {
+ Optional<FixItHint> FixInclude = Inserter->CreateIncludeInsertion(
+ /*FileID=*/SM->getMainFileID(), /*Header=*/"algorithm",
+ /*IsAngled=*/true);
+ if (FixInclude)
+ Diag << *FixInclude;
+}
+
+} // namespace modernize
+} // namespace tidy
+} // namespace clang
Index: clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
===================================================================
--- clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -21,6 +21,7 @@
#include "RawStringLiteralCheck.h"
#include "RedundantVoidArgCheck.h"
#include "ReplaceAutoPtrCheck.h"
+#include "ReplaceMemcpyByStdCopy.h"
#include "ReplaceRandomShuffleCheck.h"
#include "ReturnBracedInitListCheck.h"
#include "ShrinkToFitCheck.h"
@@ -67,6 +68,8 @@
"modernize-redundant-void-arg");
CheckFactories.registerCheck<ReplaceAutoPtrCheck>(
"modernize-replace-auto-ptr");
+ CheckFactories.registerCheck<ReplaceMemcpyByStdCopy>(
+ "modernize-replace-memcpy-by-stdcopy");
CheckFactories.registerCheck<ReplaceRandomShuffleCheck>(
"modernize-replace-random-shuffle");
CheckFactories.registerCheck<ReturnBracedInitListCheck>(
Index: clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
===================================================================
--- clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -16,6 +16,7 @@
RawStringLiteralCheck.cpp
RedundantVoidArgCheck.cpp
ReplaceAutoPtrCheck.cpp
+ ReplaceMemcpyByStdCopy.cpp
ReplaceRandomShuffleCheck.cpp
ReturnBracedInitListCheck.cpp
ShrinkToFitCheck.cpp
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits