[clang-tools-extra] r301167 - [clang-tidy] New check: modernize-replace-random-shuffle.
Mads Ravn via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 24 02:27:21 PDT 2017
Author: madsravn
Date: Mon Apr 24 04:27:20 2017
New Revision: 301167
URL: http://llvm.org/viewvc/llvm-project?rev=301167&view=rev
Log:
[clang-tidy] New check: modernize-replace-random-shuffle.
This check will find occurrences of ``std::random_shuffle`` and replace it with ``std::shuffle``. In C++17 ``std::random_shuffle`` will no longer be available and thus we need to replace it.
Example of case that it fixes
```
std::vector<int> v;
// First example
std::random_shuffle(vec.begin(), vec.end());
```
Reviewers: hokein, aaron.ballman, alexfh, malcolm.parsons, mclow.lists
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D30158
Added:
clang-tools-extra/trunk/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp
clang-tools-extra/trunk/clang-tidy/modernize/ReplaceRandomShuffleCheck.h
clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-replace-random-shuffle.rst
clang-tools-extra/trunk/test/clang-tidy/modernize-replace-random-shuffle.cpp
Modified:
clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt
clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp
clang-tools-extra/trunk/docs/ReleaseNotes.rst
clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst
Modified: clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt?rev=301167&r1=301166&r2=301167&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt Mon Apr 24 04:27:20 2017
@@ -13,6 +13,7 @@ add_clang_library(clangTidyModernizeModu
RawStringLiteralCheck.cpp
RedundantVoidArgCheck.cpp
ReplaceAutoPtrCheck.cpp
+ ReplaceRandomShuffleCheck.cpp
ReturnBracedInitListCheck.cpp
ShrinkToFitCheck.cpp
UseAutoCheck.cpp
Modified: clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp?rev=301167&r1=301166&r2=301167&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp Mon Apr 24 04:27:20 2017
@@ -19,6 +19,7 @@
#include "RawStringLiteralCheck.h"
#include "RedundantVoidArgCheck.h"
#include "ReplaceAutoPtrCheck.h"
+#include "ReplaceRandomShuffleCheck.h"
#include "ReturnBracedInitListCheck.h"
#include "ShrinkToFitCheck.h"
#include "UseAutoCheck.h"
@@ -54,6 +55,8 @@ public:
"modernize-redundant-void-arg");
CheckFactories.registerCheck<ReplaceAutoPtrCheck>(
"modernize-replace-auto-ptr");
+ CheckFactories.registerCheck<ReplaceRandomShuffleCheck>(
+ "modernize-replace-random-shuffle");
CheckFactories.registerCheck<ReturnBracedInitListCheck>(
"modernize-return-braced-init-list");
CheckFactories.registerCheck<ShrinkToFitCheck>("modernize-shrink-to-fit");
Added: clang-tools-extra/trunk/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp?rev=301167&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp (added)
+++ clang-tools-extra/trunk/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp Mon Apr 24 04:27:20 2017
@@ -0,0 +1,109 @@
+//===--- ReplaceRandomShuffleCheck.cpp - clang-tidy------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ReplaceRandomShuffleCheck.h"
+#include "../utils/FixItHintUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace modernize {
+
+ReplaceRandomShuffleCheck::ReplaceRandomShuffleCheck(StringRef Name,
+ ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context),
+ IncludeStyle(utils::IncludeSorter::parseIncludeStyle(
+ Options.get("IncludeStyle", "llvm"))) {}
+
+void ReplaceRandomShuffleCheck::registerMatchers(MatchFinder *Finder) {
+ if (!getLangOpts().CPlusPlus11)
+ return;
+
+ const auto Begin = hasArgument(0, expr());
+ const auto End = hasArgument(1, expr());
+ const auto RandomFunc = hasArgument(2, expr().bind("randomFunc"));
+ Finder->addMatcher(
+ callExpr(anyOf(allOf(Begin, End, argumentCountIs(2)),
+ allOf(Begin, End, RandomFunc, argumentCountIs(3))),
+ hasDeclaration(functionDecl(hasName("::std::random_shuffle"))),
+ has(implicitCastExpr(has(declRefExpr().bind("name")))))
+ .bind("match"),
+ this);
+}
+
+void ReplaceRandomShuffleCheck::registerPPCallbacks(
+ CompilerInstance &Compiler) {
+ IncludeInserter = llvm::make_unique<utils::IncludeInserter>(
+ Compiler.getSourceManager(), Compiler.getLangOpts(), IncludeStyle);
+ Compiler.getPreprocessor().addPPCallbacks(
+ IncludeInserter->CreatePPCallbacks());
+}
+
+void ReplaceRandomShuffleCheck::storeOptions(
+ ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "IncludeStyle",
+ utils::IncludeSorter::toString(IncludeStyle));
+}
+
+void ReplaceRandomShuffleCheck::check(const MatchFinder::MatchResult &Result) {
+ const auto *MatchedDecl = Result.Nodes.getNodeAs<DeclRefExpr>("name");
+ const auto *MatchedArgumentThree = Result.Nodes.getNodeAs<Expr>("randomFunc");
+ const auto *MatchedCallExpr = Result.Nodes.getNodeAs<CallExpr>("match");
+
+ if (MatchedCallExpr->getLocStart().isMacroID())
+ return;
+
+ auto Diag = [&] {
+ if (MatchedCallExpr->getNumArgs() == 3) {
+ auto DiagL =
+ diag(MatchedCallExpr->getLocStart(),
+ "'std::random_shuffle' has been removed in C++17; use "
+ "'std::shuffle' and an alternative random mechanism instead");
+ DiagL << FixItHint::CreateReplacement(
+ MatchedArgumentThree->getSourceRange(),
+ "std::mt19937(std::random_device()())");
+ return DiagL;
+ } else {
+ auto DiagL = diag(MatchedCallExpr->getLocStart(),
+ "'std::random_shuffle' has been removed in C++17; use "
+ "'std::shuffle' instead");
+ DiagL << FixItHint::CreateInsertion(
+ MatchedCallExpr->getRParenLoc(),
+ ", std::mt19937(std::random_device()())");
+ return DiagL;
+ }
+ }();
+
+ std::string NewName = "shuffle";
+ StringRef ContainerText = Lexer::getSourceText(
+ CharSourceRange::getTokenRange(MatchedDecl->getSourceRange()),
+ *Result.SourceManager, getLangOpts());
+ if (ContainerText.startswith("std::"))
+ NewName = "std::" + NewName;
+
+ Diag << FixItHint::CreateRemoval(MatchedDecl->getSourceRange());
+ Diag << FixItHint::CreateInsertion(MatchedDecl->getLocStart(), NewName);
+
+ if (Optional<FixItHint> IncludeFixit =
+ IncludeInserter->CreateIncludeInsertion(
+ Result.Context->getSourceManager().getFileID(
+ MatchedCallExpr->getLocStart()),
+ "random", /*IsAngled=*/true))
+ Diag << IncludeFixit.getValue();
+}
+
+} // namespace modernize
+} // namespace tidy
+} // namespace clang
Added: clang-tools-extra/trunk/clang-tidy/modernize/ReplaceRandomShuffleCheck.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/ReplaceRandomShuffleCheck.h?rev=301167&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/modernize/ReplaceRandomShuffleCheck.h (added)
+++ clang-tools-extra/trunk/clang-tidy/modernize/ReplaceRandomShuffleCheck.h Mon Apr 24 04:27:20 2017
@@ -0,0 +1,42 @@
+//===--- ReplaceRandomShuffleCheck.h - clang-tidy----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_REPLACE_RANDOM_SHUFFLE_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_REPLACE_RANDOM_SHUFFLE_H
+
+#include "../ClangTidy.h"
+#include "../utils/IncludeInserter.h"
+
+namespace clang {
+namespace tidy {
+namespace modernize {
+
+/// std::random_shuffle will be removed as of C++17. This check will find and
+/// replace all occurrences of std::random_shuffle with std::shuffle.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/modernize-replace-random-shuffle.html
+class ReplaceRandomShuffleCheck : public ClangTidyCheck {
+public:
+ ReplaceRandomShuffleCheck(StringRef Name, ClangTidyContext *Context);
+ void registerPPCallbacks(CompilerInstance &Compiler) override;
+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+private:
+ std::unique_ptr<utils::IncludeInserter> IncludeInserter;
+ const utils::IncludeSorter::IncludeStyle IncludeStyle;
+};
+
+} // namespace modernize
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_REPLACE_RANDOM_SHUFFLE_H
Modified: clang-tools-extra/trunk/docs/ReleaseNotes.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/ReleaseNotes.rst?rev=301167&r1=301166&r2=301167&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/ReleaseNotes.rst (original)
+++ clang-tools-extra/trunk/docs/ReleaseNotes.rst Mon Apr 24 04:27:20 2017
@@ -81,6 +81,11 @@ Improvements to clang-tidy
Adds checks that implement the `High Integrity C++ Coding Standard <http://www.codingstandard.com/section/index/>`_ and other safety
standards. Many checks are aliased to other modules.
+- New `modernize-replace-random-shuffle
+ <http://clang.llvm.org/extra/clang-tidy/checks/modernize-replace-random-shuffle.html>`_ check
+
+ Finds and fixes usage of ``std::random_shuffle`` as the function has been removed from C++17.
+
- New `modernize-return-braced-init-list
<http://clang.llvm.org/extra/clang-tidy/checks/modernize-return-braced-init-list.html>`_ check
Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst?rev=301167&r1=301166&r2=301167&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst (original)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst Mon Apr 24 04:27:20 2017
@@ -124,6 +124,7 @@ Clang-Tidy Checks
modernize-raw-string-literal
modernize-redundant-void-arg
modernize-replace-auto-ptr
+ modernize-replace-random-shuffle
modernize-return-braced-init-list
modernize-shrink-to-fit
modernize-use-auto
Added: clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-replace-random-shuffle.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-replace-random-shuffle.rst?rev=301167&view=auto
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-replace-random-shuffle.rst (added)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-replace-random-shuffle.rst Mon Apr 24 04:27:20 2017
@@ -0,0 +1,28 @@
+.. title:: clang-tidy - modernize-replace-random-shuffle
+
+modernize-replace-random-shuffle
+================================
+
+This check will find occurrences of ``std::random_shuffle`` and replace it with ``std::shuffle``. In C++17 ``std::random_shuffle`` will no longer be available and thus we need to replace it.
+
+Below are two examples of what kind of occurrences will be found and two examples of what it will be replaced with.
+
+.. code-block:: c++
+
+ std::vector<int> v;
+
+ // First example
+ std::random_shuffle(vec.begin(), vec.end());
+
+ // Second example
+ std::random_shuffle(vec.begin(), vec.end(), randomFun);
+
+Both of these examples will be replaced with:
+
+.. code-block:: c++
+
+ std::shuffle(vec.begin(), vec.end(), std::mt19937(std::random_device()()));
+
+The second example will also receive a warning that ``randomFunc`` is no longer supported in the same way as before so if the user wants the same functionality, the user will need to change the implementation of the ``randomFunc``.
+
+One thing to be aware of here is that ``std::random_device`` is quite expensive to initialize. So if you are using the code in a performance critical place, you probably want to initialize it elsewhere.
Added: clang-tools-extra/trunk/test/clang-tidy/modernize-replace-random-shuffle.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-replace-random-shuffle.cpp?rev=301167&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/modernize-replace-random-shuffle.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/modernize-replace-random-shuffle.cpp Mon Apr 24 04:27:20 2017
@@ -0,0 +1,57 @@
+// RUN: %check_clang_tidy %s modernize-replace-random-shuffle %t -- -- -std=c++11
+
+//CHECK-FIXES: #include <random>
+
+namespace std {
+template <typename T> struct vec_iterator {
+ T *ptr;
+ vec_iterator operator++(int);
+};
+
+template <typename T> struct vector {
+ typedef vec_iterator<T> iterator;
+
+ iterator begin();
+ iterator end();
+};
+
+template <typename FwIt>
+void random_shuffle(FwIt begin, FwIt end);
+
+template <typename FwIt, typename randomFunc>
+void random_shuffle(FwIt begin, FwIt end, randomFunc& randomfunc);
+
+template <typename FwIt>
+void shuffle(FwIt begin, FwIt end);
+} // namespace std
+
+// Random Func
+int myrandom (int i) { return i;}
+
+using namespace std;
+
+int main() {
+ std::vector<int> vec;
+
+ std::random_shuffle(vec.begin(), vec.end());
+ // CHECK-MESSAGE: [[@LINE-1]]:3: warning: 'std::random_shuffle' has been removed in C++17; use 'std::shuffle' instead
+ // CHECK-FIXES: std::shuffle(vec.begin(), vec.end(), std::mt19937(std::random_device()()));
+
+ std::shuffle(vec.begin(), vec.end());
+
+ random_shuffle(vec.begin(), vec.end());
+ // CHECK-MESSAGE: [[@LINE-1]]:3: warning: 'std::random_shuffle' has been removed in C++17; use 'std::shuffle' instead
+ // CHECK-FIXES: shuffle(vec.begin(), vec.end(), std::mt19937(std::random_device()()));
+
+ std::random_shuffle(vec.begin(), vec.end(), myrandom);
+ // CHECK-MESSAGE: [[@LINE-1]]:3: warning: 'std::random_shuffle' has been removed in C++17; use 'std::shuffle' and an alternative random mechanism instead
+ // CHECK-FIXES: std::shuffle(vec.begin(), vec.end(), std::mt19937(std::random_device()()));
+
+ random_shuffle(vec.begin(), vec.end(), myrandom);
+ // CHECK-MESSAGE: [[@LINE-1]]:3: warning: 'std::random_shuffle' has been removed in C++17; use 'std::shuffle' and an alternative random mechanism instead
+ // CHECK-FIXES: shuffle(vec.begin(), vec.end(), std::mt19937(std::random_device()()));
+
+ shuffle(vec.begin(), vec.end());
+
+ return 0;
+}
More information about the cfe-commits
mailing list