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; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits