Author: malcolm.parsons Date: Thu Nov 10 10:46:59 2016 New Revision: 286472
URL: http://llvm.org/viewvc/llvm-project?rev=286472&view=rev Log: [clang-tidy] Add modernize-use-equals-delete check Summary: Fixes PR27872 Reviewers: klimek, hokein, alexfh, aaron.ballman Subscribers: Prazek, Eugene.Zelenko, danielmarjamaki, cfe-commits, mgorny Differential Revision: https://reviews.llvm.org/D26138 Added: clang-tools-extra/trunk/clang-tidy/modernize/UseEqualsDeleteCheck.cpp clang-tools-extra/trunk/clang-tidy/modernize/UseEqualsDeleteCheck.h clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-equals-delete.rst clang-tools-extra/trunk/test/clang-tidy/modernize-use-equals-delete.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 clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-default.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=286472&r1=286471&r2=286472&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt Thu Nov 10 10:46:59 2016 @@ -18,6 +18,7 @@ add_clang_library(clangTidyModernizeModu UseBoolLiteralsCheck.cpp UseDefaultCheck.cpp UseEmplaceCheck.cpp + UseEqualsDeleteCheck.cpp UseNullptrCheck.cpp UseOverrideCheck.cpp UseUsingCheck.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=286472&r1=286471&r2=286472&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp Thu Nov 10 10:46:59 2016 @@ -24,6 +24,7 @@ #include "UseBoolLiteralsCheck.h" #include "UseDefaultCheck.h" #include "UseEmplaceCheck.h" +#include "UseEqualsDeleteCheck.h" #include "UseNullptrCheck.h" #include "UseOverrideCheck.h" #include "UseUsingCheck.h" @@ -56,6 +57,8 @@ public: "modernize-use-bool-literals"); CheckFactories.registerCheck<UseDefaultCheck>("modernize-use-default"); CheckFactories.registerCheck<UseEmplaceCheck>("modernize-use-emplace"); + CheckFactories.registerCheck<UseEqualsDeleteCheck>( + "modernize-use-equals-delete"); CheckFactories.registerCheck<UseNullptrCheck>("modernize-use-nullptr"); CheckFactories.registerCheck<UseOverrideCheck>("modernize-use-override"); CheckFactories.registerCheck<UseUsingCheck>("modernize-use-using"); Added: clang-tools-extra/trunk/clang-tidy/modernize/UseEqualsDeleteCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/UseEqualsDeleteCheck.cpp?rev=286472&view=auto ============================================================================== --- clang-tools-extra/trunk/clang-tidy/modernize/UseEqualsDeleteCheck.cpp (added) +++ clang-tools-extra/trunk/clang-tidy/modernize/UseEqualsDeleteCheck.cpp Thu Nov 10 10:46:59 2016 @@ -0,0 +1,69 @@ +//===--- UseEqualsDeleteCheck.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 "UseEqualsDeleteCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace modernize { + +static const char SpecialFunction[] = "SpecialFunction"; +static const char DeletedNotPublic[] = "DeletedNotPublic"; + +void UseEqualsDeleteCheck::registerMatchers(MatchFinder *Finder) { + auto PrivateSpecialFn = cxxMethodDecl( + isPrivate(), + anyOf(cxxConstructorDecl(anyOf(isDefaultConstructor(), + isCopyConstructor(), isMoveConstructor())), + cxxMethodDecl( + anyOf(isCopyAssignmentOperator(), isMoveAssignmentOperator())), + cxxDestructorDecl())); + + Finder->addMatcher( + cxxMethodDecl( + PrivateSpecialFn, + unless(anyOf(hasBody(stmt()), isDefaulted(), isDeleted(), + // Ensure that all methods except private special member + // functions are defined. + hasParent(cxxRecordDecl(hasMethod(unless( + anyOf(PrivateSpecialFn, hasBody(stmt()), isPure(), + isDefaulted(), isDeleted())))))))) + .bind(SpecialFunction), + this); + + Finder->addMatcher( + cxxMethodDecl(isDeleted(), unless(isPublic())).bind(DeletedNotPublic), + this); +} + +void UseEqualsDeleteCheck::check(const MatchFinder::MatchResult &Result) { + if (const auto *Func = + Result.Nodes.getNodeAs<CXXMethodDecl>(SpecialFunction)) { + SourceLocation EndLoc = Lexer::getLocForEndOfToken( + Func->getLocEnd(), 0, *Result.SourceManager, getLangOpts()); + + // FIXME: Improve FixItHint to make method public + diag(Func->getLocation(), + "use '= delete' to prohibit calling of a special member function") + << FixItHint::CreateInsertion(EndLoc, " = delete"); + } else if (const auto *Func = + Result.Nodes.getNodeAs<CXXMethodDecl>(DeletedNotPublic)) { + // FIXME: Add FixItHint to make method public + diag(Func->getLocation(), "deleted member function should be public"); + } +} + +} // namespace modernize +} // namespace tidy +} // namespace clang Added: clang-tools-extra/trunk/clang-tidy/modernize/UseEqualsDeleteCheck.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/UseEqualsDeleteCheck.h?rev=286472&view=auto ============================================================================== --- clang-tools-extra/trunk/clang-tidy/modernize/UseEqualsDeleteCheck.h (added) +++ clang-tools-extra/trunk/clang-tidy/modernize/UseEqualsDeleteCheck.h Thu Nov 10 10:46:59 2016 @@ -0,0 +1,50 @@ +//===--- UseEqualsDeleteCheck.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_USE_EQUALS_DELETE_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_EQUALS_DELETE_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace modernize { + +/// \brief Mark unimplemented private special member functions with '= delete'. +/// \code +/// struct A { +/// private: +/// A(const A&); +/// A& operator=(const A&); +/// }; +/// \endcode +/// Is converted to: +/// \code +/// struct A { +/// private: +/// A(const A&) = delete; +/// A& operator=(const A&) = delete; +/// }; +/// \endcode +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/modernize-use-equals-delete.html +class UseEqualsDeleteCheck : public ClangTidyCheck { +public: + UseEqualsDeleteCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace modernize +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_EQUALS_DELETE_H Modified: clang-tools-extra/trunk/docs/ReleaseNotes.rst URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/ReleaseNotes.rst?rev=286472&r1=286471&r2=286472&view=diff ============================================================================== --- clang-tools-extra/trunk/docs/ReleaseNotes.rst (original) +++ clang-tools-extra/trunk/docs/ReleaseNotes.rst Thu Nov 10 10:46:59 2016 @@ -91,6 +91,11 @@ Improvements to clang-tidy <http://clang.llvm.org/extra/clang-tidy/checks/modernize-use-auto.html>`_ check now warns about variable declarations that are initialized with a cast. +- New `modernize-use-equals-delete + <http://clang.llvm.org/extra/clang-tidy/checks/modernize-use-equals-delete.html>`_ check + + Adds ``= delete`` to unimplemented private special member functions. + - New `mpi-buffer-deref <http://clang.llvm.org/extra/clang-tidy/checks/mpi-buffer-deref.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=286472&r1=286471&r2=286472&view=diff ============================================================================== --- clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst (original) +++ clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst Thu Nov 10 10:46:59 2016 @@ -111,6 +111,7 @@ Clang-Tidy Checks modernize-use-bool-literals modernize-use-default modernize-use-emplace + modernize-use-equals-delete modernize-use-nullptr modernize-use-override modernize-use-using Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-default.rst URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-default.rst?rev=286472&r1=286471&r2=286472&view=diff ============================================================================== --- clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-default.rst (original) +++ clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-default.rst Thu Nov 10 10:46:59 2016 @@ -25,5 +25,4 @@ defaulted functions as trivial. A::~A() = default; .. note:: - Copy-constructor, copy-assignment operator, move-constructor and - move-assignment operator are not supported yet. + Move-constructor and move-assignment operator are not supported yet. Added: clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-equals-delete.rst URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-equals-delete.rst?rev=286472&view=auto ============================================================================== --- clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-equals-delete.rst (added) +++ clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-equals-delete.rst Thu Nov 10 10:46:59 2016 @@ -0,0 +1,25 @@ +.. title:: clang-tidy - modernize-use-equals-delete + +modernize-use-equals-delete +=========================== + +This check marks unimplemented private special member functions with ``= delete``. +To avoid false-positives, this check only applies in a translation unit that has +all other member functions implemented. + +.. code-block:: c++ + + struct A { + private: + A(const A&); + A& operator=(const A&); + }; + + // becomes + + struct A { + private: + A(const A&) = delete; + A& operator=(const A&) = delete; + }; + Added: clang-tools-extra/trunk/test/clang-tidy/modernize-use-equals-delete.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-use-equals-delete.cpp?rev=286472&view=auto ============================================================================== --- clang-tools-extra/trunk/test/clang-tidy/modernize-use-equals-delete.cpp (added) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-use-equals-delete.cpp Thu Nov 10 10:46:59 2016 @@ -0,0 +1,134 @@ +// RUN: %check_clang_tidy %s modernize-use-equals-delete %t + +struct PositivePrivate { +private: + PositivePrivate(); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete] + // CHECK-FIXES: PositivePrivate() = delete; + PositivePrivate(const PositivePrivate &); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete] + // CHECK-FIXES: PositivePrivate(const PositivePrivate &) = delete; + PositivePrivate &operator=(const PositivePrivate &); + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete] + // CHECK-FIXES: PositivePrivate &operator=(const PositivePrivate &) = delete; + PositivePrivate(PositivePrivate &&); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete] + // CHECK-FIXES: PositivePrivate(PositivePrivate &&) = delete; + PositivePrivate &operator=(PositivePrivate &&); + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete] + // CHECK-FIXES: PositivePrivate &operator=(PositivePrivate &&) = delete; + ~PositivePrivate(); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete] + // CHECK-FIXES: ~PositivePrivate() = delete; +}; + +struct NegativePublic { + NegativePublic(const NegativePublic &); +}; + +struct NegativeProtected { +protected: + NegativeProtected(const NegativeProtected &); +}; + +struct PositiveInlineMember { + int foo() { return 0; } + +private: + PositiveInlineMember(const PositiveInlineMember &); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete] + // CHECK-FIXES: PositiveInlineMember(const PositiveInlineMember &) = delete; +}; + +struct PositiveOutOfLineMember { + int foo(); + +private: + PositiveOutOfLineMember(const PositiveOutOfLineMember &); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete] + // CHECK-FIXES: PositiveOutOfLineMember(const PositiveOutOfLineMember &) = delete; +}; + +int PositiveOutOfLineMember::foo() { return 0; } + +struct PositiveAbstractMember { + virtual int foo() = 0; + +private: + PositiveAbstractMember(const PositiveAbstractMember &); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete] + // CHECK-FIXES: PositiveAbstractMember(const PositiveAbstractMember &) = delete; +}; + +struct NegativeMemberNotImpl { + int foo(); + +private: + NegativeMemberNotImpl(const NegativeMemberNotImpl &); +}; + +struct NegativeStaticMemberNotImpl { + static int foo(); + +private: + NegativeStaticMemberNotImpl(const NegativeStaticMemberNotImpl &); +}; + +struct NegativeInline { +private: + NegativeInline(const NegativeInline &) {} +}; + +struct NegativeOutOfLine { +private: + NegativeOutOfLine(const NegativeOutOfLine &); +}; + +NegativeOutOfLine::NegativeOutOfLine(const NegativeOutOfLine &) {} + +struct NegativeConstructNotImpl { + NegativeConstructNotImpl(); + +private: + NegativeConstructNotImpl(const NegativeConstructNotImpl &); +}; + +struct PositiveDefaultedConstruct { + PositiveDefaultedConstruct() = default; + +private: + PositiveDefaultedConstruct(const PositiveDefaultedConstruct &); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete] + // CHECK-FIXES: PositiveDefaultedConstruct(const PositiveDefaultedConstruct &) = delete; +}; + +struct PositiveDeletedConstruct { + PositiveDeletedConstruct() = delete; + +private: + PositiveDeletedConstruct(const PositiveDeletedConstruct &); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= delete' to prohibit calling of a special member function [modernize-use-equals-delete] + // CHECK-FIXES: PositiveDeletedConstruct(const PositiveDeletedConstruct &) = delete; +}; + +struct NegativeDefaulted { +private: + NegativeDefaulted(const NegativeDefaulted &) = default; +}; + +struct PrivateDeleted { +private: + PrivateDeleted(const PrivateDeleted &) = delete; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: deleted member function should be public [modernize-use-equals-delete] +}; + +struct ProtectedDeleted { +protected: + ProtectedDeleted(const ProtectedDeleted &) = delete; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: deleted member function should be public [modernize-use-equals-delete] +}; + +struct PublicDeleted { +public: + PublicDeleted(const PublicDeleted &) = delete; +}; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits