Author: prazek Date: Mon May 2 11:56:39 2016 New Revision: 268253 URL: http://llvm.org/viewvc/llvm-project?rev=268253&view=rev Log: [clang-tidy] Add modernize-make-shared check
Because modernize-make-shared do almost the same job as modernize-make-unique, I refactored common code to MakeSmartPtrCheck. http://reviews.llvm.org/D19183 Added: clang-tools-extra/trunk/clang-tidy/modernize/MakeSharedCheck.cpp clang-tools-extra/trunk/clang-tidy/modernize/MakeSharedCheck.h clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.cpp - copied, changed from r268140, clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.h clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-shared.rst clang-tools-extra/trunk/test/clang-tidy/modernize-make-shared.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.h 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=268253&r1=268252&r2=268253&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt Mon May 2 11:56:39 2016 @@ -4,6 +4,8 @@ add_clang_library(clangTidyModernizeModu DeprecatedHeadersCheck.cpp LoopConvertCheck.cpp LoopConvertUtils.cpp + MakeSmartPtrCheck.cpp + MakeSharedCheck.cpp MakeUniqueCheck.cpp ModernizeTidyModule.cpp PassByValueCheck.cpp Added: clang-tools-extra/trunk/clang-tidy/modernize/MakeSharedCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/MakeSharedCheck.cpp?rev=268253&view=auto ============================================================================== --- clang-tools-extra/trunk/clang-tidy/modernize/MakeSharedCheck.cpp (added) +++ clang-tools-extra/trunk/clang-tidy/modernize/MakeSharedCheck.cpp Mon May 2 11:56:39 2016 @@ -0,0 +1,31 @@ +//===--- MakeSharedCheck.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 "MakeSharedCheck.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace modernize { + +MakeSharedCheck::MakeSharedCheck(StringRef Name, ClangTidyContext *Context) + : MakeSmartPtrCheck(Name, Context, "std::make_shared") {} + +MakeSharedCheck::SmartPtrTypeMatcher +MakeSharedCheck::getSmartPointerTypeMatcher() const { + return qualType(hasDeclaration(classTemplateSpecializationDecl( + matchesName("::std::shared_ptr"), templateArgumentCountIs(1), + hasTemplateArgument( + 0, templateArgument(refersToType(qualType().bind(PointerType))))))); +} + +} // namespace modernize +} // namespace tidy +} // namespace clang Added: clang-tools-extra/trunk/clang-tidy/modernize/MakeSharedCheck.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/MakeSharedCheck.h?rev=268253&view=auto ============================================================================== --- clang-tools-extra/trunk/clang-tidy/modernize/MakeSharedCheck.h (added) +++ clang-tools-extra/trunk/clang-tidy/modernize/MakeSharedCheck.h Mon May 2 11:56:39 2016 @@ -0,0 +1,43 @@ +//===--- MakeSharedCheck.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_MAKE_SHARED_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MAKE_SHARED_H + +#include "MakeSmartPtrCheck.h" + +namespace clang { +namespace tidy { +namespace modernize { + +/// Replace the pattern: +/// \code +/// std::shared_ptr<type>(new type(args...)) +/// \endcode +/// +/// With the safer version: +/// \code +/// std::make_shared<type>(args...) +/// \endcode +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/modernize-make-shared.html +class MakeSharedCheck : public MakeSmartPtrCheck { +public: + MakeSharedCheck(StringRef Name, ClangTidyContext *Context); + +protected: + SmartPtrTypeMatcher getSmartPointerTypeMatcher() const override; +}; + +} // namespace modernize +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MAKE_SHARED_H Copied: clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.cpp (from r268140, clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp) URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.cpp?p2=clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.cpp&p1=clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp&r1=268140&r2=268253&rev=268253&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.cpp Mon May 2 11:56:39 2016 @@ -1,4 +1,4 @@ -//===--- MakeUniqueCheck.cpp - clang-tidy----------------------------------===// +//===--- MakeSmartPtrCheck.cpp - clang-tidy--------------------------------===// // // The LLVM Compiler Infrastructure // @@ -7,9 +7,7 @@ // //===----------------------------------------------------------------------===// -#include "MakeUniqueCheck.h" -#include "clang/AST/ASTContext.h" -#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "MakeSharedCheck.h" #include "clang/Lex/Lexer.h" using namespace clang::ast_matchers; @@ -18,40 +16,36 @@ namespace clang { namespace tidy { namespace modernize { -static const char PointerType[] = "pointerType"; -static const char ConstructorCall[] = "constructorCall"; -static const char NewExpression[] = "newExpression"; - -void MakeUniqueCheck::registerMatchers(MatchFinder *Finder) { - if (getLangOpts().CPlusPlus11) { - Finder->addMatcher( - cxxBindTemporaryExpr(has( - cxxConstructExpr( - hasType(qualType(hasDeclaration(classTemplateSpecializationDecl( - matchesName("::std::unique_ptr"), - templateArgumentCountIs(2), - hasTemplateArgument(0, templateArgument(refersToType( - qualType().bind(PointerType)))), - hasTemplateArgument( - 1, templateArgument(refersToType(qualType( - hasDeclaration(classTemplateSpecializationDecl( - matchesName("::std::default_delete"), - templateArgumentCountIs(1), - hasTemplateArgument( - 0, templateArgument(refersToType( - qualType(equalsBoundNode( - PointerType))))))))))))))), - argumentCountIs(1), - hasArgument( - 0, cxxNewExpr(hasType(pointsTo(qualType(hasCanonicalType( - equalsBoundNode(PointerType)))))) - .bind(NewExpression))) - .bind(ConstructorCall))), - this); - } +const char MakeSmartPtrCheck::PointerType[] = "pointerType"; +const char MakeSmartPtrCheck::ConstructorCall[] = "constructorCall"; +const char MakeSmartPtrCheck::NewExpression[] = "newExpression"; + +MakeSmartPtrCheck::MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context, + std::string makeSmartPtrFunctionName) + : ClangTidyCheck(Name, Context), + makeSmartPtrFunctionName(std::move(makeSmartPtrFunctionName)) {} + +void MakeSmartPtrCheck::registerMatchers(ast_matchers::MatchFinder *Finder) { + if (!getLangOpts().CPlusPlus11) + return; + + Finder->addMatcher( + cxxBindTemporaryExpr( + has(cxxConstructExpr( + hasType(getSmartPointerTypeMatcher()), argumentCountIs(1), + hasArgument( + 0, cxxNewExpr(hasType(pointsTo(qualType(hasCanonicalType( + equalsBoundNode(PointerType)))))) + .bind(NewExpression))) + .bind(ConstructorCall))), + this); } -void MakeUniqueCheck::check(const MatchFinder::MatchResult &Result) { +void MakeSmartPtrCheck::check(const MatchFinder::MatchResult &Result) { + // 'smart_ptr' refers to 'std::shared_ptr' or 'std::unique_ptr' or other + // pointer, 'make_smart_ptr' refers to 'std::make_shared' or + // 'std::make_unique' or other function that creates smart_ptr. + SourceManager &SM = *Result.SourceManager; const auto *Construct = Result.Nodes.getNodeAs<CXXConstructExpr>(ConstructorCall); @@ -71,7 +65,8 @@ void MakeUniqueCheck::check(const MatchF if (Invalid) return; - auto Diag = diag(ConstructCallStart, "use std::make_unique instead"); + auto Diag = diag(ConstructCallStart, "use %0 instead") + << makeSmartPtrFunctionName; // Find the location of the template's left angle. size_t LAngle = ExprStr.find("<"); @@ -88,9 +83,9 @@ void MakeUniqueCheck::check(const MatchF Diag << FixItHint::CreateReplacement( CharSourceRange::getCharRange(ConstructCallStart, ConstructCallEnd), - "std::make_unique"); + makeSmartPtrFunctionName); - // If the unique_ptr is built with brace enclosed direct initialization, use + // If the smart_ptr is built with brace enclosed direct initialization, use // parenthesis instead. if (Construct->isListInitialization()) { SourceRange BraceRange = Construct->getParenOrBraceRange(); @@ -124,19 +119,19 @@ void MakeUniqueCheck::check(const MatchF if (const auto *NewConstruct = New->getConstructExpr()) { // Direct initialization with initialization list. // struct S { S(int x) {} }; - // std::unique_ptr<S>(new S{5}); + // smart_ptr<S>(new S{5}); // The arguments in the initialization list are going to be forwarded to // the constructor, so this has to be replaced with: // struct S { S(int x) {} }; - // std::make_unique<S>(5); + // std::make_smart_ptr<S>(5); InitRange = SourceRange( NewConstruct->getParenOrBraceRange().getBegin().getLocWithOffset(1), NewConstruct->getParenOrBraceRange().getEnd().getLocWithOffset(-1)); } else { // Aggregate initialization. - // std::unique_ptr<Pair>(new Pair{first, second}); + // smart_ptr<Pair>(new Pair{first, second}); // Has to be replaced with: - // std::make_unique<Pair>(Pair{first, second}); + // smart_ptr<Pair>(Pair{first, second}); InitRange = SourceRange( New->getAllocatedTypeSourceInfo()->getTypeLoc().getLocStart(), New->getInitializer()->getSourceRange().getEnd()); Added: clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.h?rev=268253&view=auto ============================================================================== --- clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.h (added) +++ clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.h Mon May 2 11:56:39 2016 @@ -0,0 +1,50 @@ +//===--- MakeSmartPtrCheck.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_MAKE_SMART_PTR_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MAKE_SMART_PTR_H + +#include "../ClangTidy.h" +#include <string> + +namespace clang { +namespace tidy { +namespace modernize { + +/// Base class for MakeSharedCheck and MakeUniqueCheck. +class MakeSmartPtrCheck : public ClangTidyCheck { +public: + MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context, + std::string makeSmartPtrFunctionName); + void registerMatchers(ast_matchers::MatchFinder *Finder) override final; + void + check(const ast_matchers::MatchFinder::MatchResult &Result) override final; + +protected: + using SmartPtrTypeMatcher = ast_matchers::internal::BindableMatcher<QualType>; + + /// Returns matcher that match with different smart pointer types. + /// + /// Requires to bind pointer type (qualType) with PointerType string declared + /// in this class. + virtual SmartPtrTypeMatcher getSmartPointerTypeMatcher() const = 0; + + static const char PointerType[]; + static const char ConstructorCall[]; + static const char NewExpression[]; + +private: + std::string makeSmartPtrFunctionName; +}; + +} // namespace modernize +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MAKE_SMART_PTR_H Modified: clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp?rev=268253&r1=268252&r2=268253&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp Mon May 2 11:56:39 2016 @@ -8,9 +8,6 @@ //===----------------------------------------------------------------------===// #include "MakeUniqueCheck.h" -#include "clang/AST/ASTContext.h" -#include "clang/ASTMatchers/ASTMatchFinder.h" -#include "clang/Lex/Lexer.h" using namespace clang::ast_matchers; @@ -18,136 +15,24 @@ namespace clang { namespace tidy { namespace modernize { -static const char PointerType[] = "pointerType"; -static const char ConstructorCall[] = "constructorCall"; -static const char NewExpression[] = "newExpression"; - -void MakeUniqueCheck::registerMatchers(MatchFinder *Finder) { - if (getLangOpts().CPlusPlus11) { - Finder->addMatcher( - cxxBindTemporaryExpr(has( - cxxConstructExpr( - hasType(qualType(hasDeclaration(classTemplateSpecializationDecl( - matchesName("::std::unique_ptr"), - templateArgumentCountIs(2), - hasTemplateArgument(0, templateArgument(refersToType( - qualType().bind(PointerType)))), - hasTemplateArgument( - 1, templateArgument(refersToType(qualType( - hasDeclaration(classTemplateSpecializationDecl( - matchesName("::std::default_delete"), - templateArgumentCountIs(1), - hasTemplateArgument( - 0, templateArgument(refersToType( - qualType(equalsBoundNode( - PointerType))))))))))))))), - argumentCountIs(1), - hasArgument( - 0, cxxNewExpr(hasType(pointsTo(qualType(hasCanonicalType( - equalsBoundNode(PointerType)))))) - .bind(NewExpression))) - .bind(ConstructorCall))), - this); - } -} - -void MakeUniqueCheck::check(const MatchFinder::MatchResult &Result) { - SourceManager &SM = *Result.SourceManager; - const auto *Construct = - Result.Nodes.getNodeAs<CXXConstructExpr>(ConstructorCall); - const auto *Type = Result.Nodes.getNodeAs<QualType>(PointerType); - const auto *New = Result.Nodes.getNodeAs<CXXNewExpr>(NewExpression); - - if (New->getNumPlacementArgs() != 0) - return; - - SourceLocation ConstructCallStart = Construct->getExprLoc(); - - bool Invalid = false; - StringRef ExprStr = Lexer::getSourceText( - CharSourceRange::getCharRange( - ConstructCallStart, Construct->getParenOrBraceRange().getBegin()), - SM, LangOptions(), &Invalid); - if (Invalid) - return; - - auto Diag = diag(ConstructCallStart, "use std::make_unique instead"); - - // Find the location of the template's left angle. - size_t LAngle = ExprStr.find("<"); - SourceLocation ConstructCallEnd; - if (LAngle == StringRef::npos) { - // If the template argument is missing (because it is part of the alias) - // we have to add it back. - ConstructCallEnd = ConstructCallStart.getLocWithOffset(ExprStr.size()); - Diag << FixItHint::CreateInsertion( - ConstructCallEnd, "<" + Type->getAsString(getLangOpts()) + ">"); - } else { - ConstructCallEnd = ConstructCallStart.getLocWithOffset(LAngle); - } - - Diag << FixItHint::CreateReplacement( - CharSourceRange::getCharRange(ConstructCallStart, ConstructCallEnd), - "std::make_unique"); - - // If the unique_ptr is built with brace enclosed direct initialization, use - // parenthesis instead. - if (Construct->isListInitialization()) { - SourceRange BraceRange = Construct->getParenOrBraceRange(); - Diag << FixItHint::CreateReplacement( - CharSourceRange::getCharRange( - BraceRange.getBegin(), BraceRange.getBegin().getLocWithOffset(1)), - "("); - Diag << FixItHint::CreateReplacement( - CharSourceRange::getCharRange(BraceRange.getEnd(), - BraceRange.getEnd().getLocWithOffset(1)), - ")"); - } - - SourceLocation NewStart = New->getSourceRange().getBegin(); - SourceLocation NewEnd = New->getSourceRange().getEnd(); - switch (New->getInitializationStyle()) { - case CXXNewExpr::NoInit: { - Diag << FixItHint::CreateRemoval(SourceRange(NewStart, NewEnd)); - break; - } - case CXXNewExpr::CallInit: { - SourceRange InitRange = New->getDirectInitRange(); - Diag << FixItHint::CreateRemoval( - SourceRange(NewStart, InitRange.getBegin())); - Diag << FixItHint::CreateRemoval(SourceRange(InitRange.getEnd(), NewEnd)); - break; - } - case CXXNewExpr::ListInit: { - // Range of the substring that we do not want to remove. - SourceRange InitRange; - if (const auto *NewConstruct = New->getConstructExpr()) { - // Direct initialization with initialization list. - // struct S { S(int x) {} }; - // std::unique_ptr<S>(new S{5}); - // The arguments in the initialization list are going to be forwarded to - // the constructor, so this has to be replaced with: - // struct S { S(int x) {} }; - // std::make_unique<S>(5); - InitRange = SourceRange( - NewConstruct->getParenOrBraceRange().getBegin().getLocWithOffset(1), - NewConstruct->getParenOrBraceRange().getEnd().getLocWithOffset(-1)); - } else { - // Aggregate initialization. - // std::unique_ptr<Pair>(new Pair{first, second}); - // Has to be replaced with: - // std::make_unique<Pair>(Pair{first, second}); - InitRange = SourceRange( - New->getAllocatedTypeSourceInfo()->getTypeLoc().getLocStart(), - New->getInitializer()->getSourceRange().getEnd()); - } - Diag << FixItHint::CreateRemoval( - CharSourceRange::getCharRange(NewStart, InitRange.getBegin())); - Diag << FixItHint::CreateRemoval( - SourceRange(InitRange.getEnd().getLocWithOffset(1), NewEnd)); - break; - } - } +MakeUniqueCheck::MakeUniqueCheck(StringRef Name, + clang::tidy::ClangTidyContext *Context) + : MakeSmartPtrCheck(Name, Context, "std::make_unique") {} + +MakeUniqueCheck::SmartPtrTypeMatcher +MakeUniqueCheck::getSmartPointerTypeMatcher() const { + return qualType(hasDeclaration(classTemplateSpecializationDecl( + matchesName("::std::unique_ptr"), templateArgumentCountIs(2), + hasTemplateArgument( + 0, templateArgument(refersToType(qualType().bind(PointerType)))), + hasTemplateArgument( + 1, templateArgument(refersToType( + qualType(hasDeclaration(classTemplateSpecializationDecl( + matchesName("::std::default_delete"), + templateArgumentCountIs(1), + hasTemplateArgument( + 0, templateArgument(refersToType(qualType( + equalsBoundNode(PointerType)))))))))))))); } } // namespace modernize Modified: clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.h?rev=268253&r1=268252&r2=268253&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.h (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.h Mon May 2 11:56:39 2016 @@ -10,7 +10,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MAKE_UNIQUE_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MAKE_UNIQUE_H -#include "../ClangTidy.h" +#include "MakeSmartPtrCheck.h" namespace clang { namespace tidy { @@ -25,12 +25,12 @@ namespace modernize { /// \code /// std::make_unique<type>(args...) /// \endcode -class MakeUniqueCheck : public ClangTidyCheck { +class MakeUniqueCheck : public MakeSmartPtrCheck { public: - MakeUniqueCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context) {} - void registerMatchers(ast_matchers::MatchFinder *Finder) override; - void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + MakeUniqueCheck(StringRef Name, ClangTidyContext *Context); + +protected: + SmartPtrTypeMatcher getSmartPointerTypeMatcher() const override; }; } // namespace modernize 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=268253&r1=268252&r2=268253&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp Mon May 2 11:56:39 2016 @@ -12,6 +12,7 @@ #include "../ClangTidyModuleRegistry.h" #include "DeprecatedHeadersCheck.h" #include "LoopConvertCheck.h" +#include "MakeSharedCheck.h" #include "MakeUniqueCheck.h" #include "PassByValueCheck.h" #include "RawStringLiteralCheck.h" @@ -35,6 +36,7 @@ public: CheckFactories.registerCheck<DeprecatedHeadersCheck>( "modernize-deprecated-headers"); CheckFactories.registerCheck<LoopConvertCheck>("modernize-loop-convert"); + CheckFactories.registerCheck<MakeSharedCheck>("modernize-make-shared"); CheckFactories.registerCheck<MakeUniqueCheck>("modernize-make-unique"); CheckFactories.registerCheck<PassByValueCheck>("modernize-pass-by-value"); CheckFactories.registerCheck<RawStringLiteralCheck>( Modified: clang-tools-extra/trunk/docs/ReleaseNotes.rst URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/ReleaseNotes.rst?rev=268253&r1=268252&r2=268253&view=diff ============================================================================== --- clang-tools-extra/trunk/docs/ReleaseNotes.rst (original) +++ clang-tools-extra/trunk/docs/ReleaseNotes.rst Mon May 2 11:56:39 2016 @@ -180,6 +180,11 @@ identified. The improvements since the Replaces C standard library headers with their C++ alternatives. +- New `modernize-make-shared + <http://clang.llvm.org/extra/clang-tidy/checks/modernize-make-shared.html>`_ check + + Replaces creation of ``std::shared_ptr`` from new expression with call to ``std::make_shared``. + - New `modernize-raw-string-literal <http://clang.llvm.org/extra/clang-tidy/checks/modernize-raw-string-literal.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=268253&r1=268252&r2=268253&view=diff ============================================================================== --- clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst (original) +++ clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst Mon May 2 11:56:39 2016 @@ -92,6 +92,7 @@ Clang-Tidy Checks misc-virtual-near-miss modernize-deprecated-headers modernize-loop-convert + modernize-make-shared modernize-make-unique modernize-pass-by-value modernize-raw-string-literal Added: clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-shared.rst URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-shared.rst?rev=268253&view=auto ============================================================================== --- clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-shared.rst (added) +++ clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-shared.rst Mon May 2 11:56:39 2016 @@ -0,0 +1,16 @@ +.. title:: clang-tidy - modernize-make-shared + +modernize-make-shared +===================== + +This check finds the creation of ``std::shared_ptr`` objects by explicitly +calling the constructor and a ``new`` expression, and replaces it with a call +to ``std::make_shared``. + +.. code-block:: c++ + + auto my_ptr = std::shared_ptr<MyPair>(new MyPair(1, 2)); + + // becomes + + auto my_ptr = std::make_shared<MyPair>(1, 2); Added: clang-tools-extra/trunk/test/clang-tidy/modernize-make-shared.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-make-shared.cpp?rev=268253&view=auto ============================================================================== --- clang-tools-extra/trunk/test/clang-tidy/modernize-make-shared.cpp (added) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-make-shared.cpp Mon May 2 11:56:39 2016 @@ -0,0 +1,200 @@ +// RUN: %check_clang_tidy %s modernize-make-shared %t + +namespace std { + +template <typename type> +class shared_ptr { +public: + shared_ptr(type *ptr); + shared_ptr(const shared_ptr<type> &t) {} + shared_ptr(shared_ptr<type> &&t) {} + ~shared_ptr(); + type &operator*() { return *ptr; } + type *operator->() { return ptr; } + type *release(); + void reset(); + void reset(type *pt); + +private: + type *ptr; +}; +} + +struct Base { + Base(); + Base(int, int); +}; + +struct Derived : public Base { + Derived(); + Derived(int, int); +}; + +struct APair { + int a, b; +}; + +struct DPair { + DPair() : a(0), b(0) {} + DPair(int x, int y) : a(y), b(x) {} + int a, b; +}; + +struct Empty {}; + +template <class T> +using shared_ptr_ = std::shared_ptr<T>; + +void *operator new(__SIZE_TYPE__ Count, void *Ptr); + +int g(std::shared_ptr<int> P); + +std::shared_ptr<Base> getPointer() { + return std::shared_ptr<Base>(new Base); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use std::make_shared instead + // CHECK-FIXES: return std::make_shared<Base>(); +} + +void basic() { + std::shared_ptr<int> P1 = std::shared_ptr<int>(new int()); + // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_shared instead [modernize-make-shared] + // CHECK-FIXES: std::shared_ptr<int> P1 = std::make_shared<int>(); + + // Without parenthesis. + std::shared_ptr<int> P2 = std::shared_ptr<int>(new int); + // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_shared instead [modernize-make-shared] + // CHECK-FIXES: std::shared_ptr<int> P2 = std::make_shared<int>(); + + // With auto. + auto P3 = std::shared_ptr<int>(new int()); + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_shared instead + // CHECK-FIXES: auto P3 = std::make_shared<int>(); + + { + // No std. + using namespace std; + shared_ptr<int> Q = shared_ptr<int>(new int()); + // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use std::make_shared instead + // CHECK-FIXES: shared_ptr<int> Q = std::make_shared<int>(); + } + + std::shared_ptr<int> R(new int()); + + // Create the shared_ptr as a parameter to a function. + int T = g(std::shared_ptr<int>(new int())); + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_shared instead + // CHECK-FIXES: int T = g(std::make_shared<int>()); + + // Only replace if the type in the template is the same than the type returned + // by the new operator. + auto Pderived = std::shared_ptr<Base>(new Derived()); + + // The pointer is returned by the function, nothing to do. + std::shared_ptr<Base> RetPtr = getPointer(); + + // This emulates std::move. + std::shared_ptr<int> Move = static_cast<std::shared_ptr<int> &&>(P1); + + // Placemenet arguments should not be removed. + int *PInt = new int; + std::shared_ptr<int> Placement = std::shared_ptr<int>(new (PInt) int{3}); +} + +void initialization(int T, Base b) { + // Test different kinds of initialization of the pointee. + + // Direct initialization with parenthesis. + std::shared_ptr<DPair> PDir1 = std::shared_ptr<DPair>(new DPair(1, T)); + // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead + // CHECK-FIXES: std::shared_ptr<DPair> PDir1 = std::make_shared<DPair>(1, T); + + // Direct initialization with braces. + std::shared_ptr<DPair> PDir2 = std::shared_ptr<DPair>(new DPair{2, T}); + // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead + // CHECK-FIXES: std::shared_ptr<DPair> PDir2 = std::make_shared<DPair>(2, T); + + // Aggregate initialization. + std::shared_ptr<APair> PAggr = std::shared_ptr<APair>(new APair{T, 1}); + // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead + // CHECK-FIXES: std::shared_ptr<APair> PAggr = std::make_shared<APair>(APair{T, 1}); + + // Test different kinds of initialization of the pointee, when the shared_ptr + // is initialized with braces. + + // Direct initialization with parenthesis. + std::shared_ptr<DPair> PDir3 = std::shared_ptr<DPair>{new DPair(3, T)}; + // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead + // CHECK-FIXES: std::shared_ptr<DPair> PDir3 = std::make_shared<DPair>(3, T); + + // Direct initialization with braces. + std::shared_ptr<DPair> PDir4 = std::shared_ptr<DPair>{new DPair{4, T}}; + // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead + // CHECK-FIXES: std::shared_ptr<DPair> PDir4 = std::make_shared<DPair>(4, T); + + // Aggregate initialization. + std::shared_ptr<APair> PAggr2 = std::shared_ptr<APair>{new APair{T, 2}}; + // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use std::make_shared instead + // CHECK-FIXES: std::shared_ptr<APair> PAggr2 = std::make_shared<APair>(APair{T, 2}); + + // Direct initialization with parenthesis, without arguments. + std::shared_ptr<DPair> PDir5 = std::shared_ptr<DPair>(new DPair()); + // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead + // CHECK-FIXES: std::shared_ptr<DPair> PDir5 = std::make_shared<DPair>(); + + // Direct initialization with braces, without arguments. + std::shared_ptr<DPair> PDir6 = std::shared_ptr<DPair>(new DPair{}); + // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead + // CHECK-FIXES: std::shared_ptr<DPair> PDir6 = std::make_shared<DPair>(); + + // Aggregate initialization without arguments. + std::shared_ptr<Empty> PEmpty = std::shared_ptr<Empty>(new Empty{}); + // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use std::make_shared instead + // CHECK-FIXES: std::shared_ptr<Empty> PEmpty = std::make_shared<Empty>(Empty{}); +} + +void aliases() { + typedef std::shared_ptr<int> IntPtr; + IntPtr Typedef = IntPtr(new int); + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use std::make_shared instead + // CHECK-FIXES: IntPtr Typedef = std::make_shared<int>(); + + // We use 'bool' instead of '_Bool'. + typedef std::shared_ptr<bool> BoolPtr; + BoolPtr BoolType = BoolPtr(new bool); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use std::make_shared instead + // CHECK-FIXES: BoolPtr BoolType = std::make_shared<bool>(); + + // We use 'Base' instead of 'struct Base'. + typedef std::shared_ptr<Base> BasePtr; + BasePtr StructType = BasePtr(new Base); +// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_shared instead +// CHECK-FIXES: BasePtr StructType = std::make_shared<Base>(); + +#define PTR shared_ptr<int> + std::shared_ptr<int> Macro = std::PTR(new int); +// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use std::make_shared instead +// CHECK-FIXES: std::shared_ptr<int> Macro = std::make_shared<int>(); +#undef PTR + + std::shared_ptr<int> Using = shared_ptr_<int>(new int); + // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use std::make_shared instead + // CHECK-FIXES: std::shared_ptr<int> Using = std::make_shared<int>(); +} + +void whitespaces() { + // clang-format off + auto Space = std::shared_ptr <int>(new int()); + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use std::make_shared instead + // CHECK-FIXES: auto Space = std::make_shared<int>(); + + auto Spaces = std :: shared_ptr <int>(new int()); + // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use std::make_shared instead + // CHECK-FIXES: auto Spaces = std::make_shared<int>(); + // clang-format on +} + +void nesting() { + auto Nest = std::shared_ptr<std::shared_ptr<int>>(new std::shared_ptr<int>(new int)); + // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use std::make_shared instead + // CHECK-FIXES: auto Nest = std::make_shared<std::shared_ptr<int>>(new int); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits