[clang-tools-extra] r266190 - [clang-tidy] Add a readability-deleted-default clang-tidy check.
Alexander Kornienko via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 13 04:33:41 PDT 2016
Author: alexfh
Date: Wed Apr 13 06:33:40 2016
New Revision: 266190
URL: http://llvm.org/viewvc/llvm-project?rev=266190&view=rev
Log:
[clang-tidy] Add a readability-deleted-default clang-tidy check.
Checks if constructors and assignment operators that are marked '= default' are
actually deleted by the compiler.
Patch by Alex Pilkiewicz!
Differential Revision: http://reviews.llvm.org/D18961
Added:
clang-tools-extra/trunk/clang-tidy/readability/DeletedDefaultCheck.cpp
clang-tools-extra/trunk/clang-tidy/readability/DeletedDefaultCheck.h
clang-tools-extra/trunk/docs/clang-tidy/checks/readability-deleted-default.rst
clang-tools-extra/trunk/test/clang-tidy/readability-deleted-default.cpp
Modified:
clang-tools-extra/trunk/clang-tidy/readability/CMakeLists.txt
clang-tools-extra/trunk/clang-tidy/readability/ReadabilityTidyModule.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/readability/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/CMakeLists.txt?rev=266190&r1=266189&r2=266190&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/readability/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/readability/CMakeLists.txt Wed Apr 13 06:33:40 2016
@@ -4,6 +4,7 @@ add_clang_library(clangTidyReadabilityMo
AvoidConstParamsInDecls.cpp
BracesAroundStatementsCheck.cpp
ContainerSizeEmptyCheck.cpp
+ DeletedDefaultCheck.cpp
ElseAfterReturnCheck.cpp
FunctionSizeCheck.cpp
IdentifierNamingCheck.cpp
Added: clang-tools-extra/trunk/clang-tidy/readability/DeletedDefaultCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/DeletedDefaultCheck.cpp?rev=266190&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/readability/DeletedDefaultCheck.cpp (added)
+++ clang-tools-extra/trunk/clang-tidy/readability/DeletedDefaultCheck.cpp Wed Apr 13 06:33:40 2016
@@ -0,0 +1,69 @@
+//===--- DeletedDefaultCheck.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 "DeletedDefaultCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+void DeletedDefaultCheck::registerMatchers(MatchFinder *Finder) {
+ // We match constructors/assignment operators that are:
+ // - explicitly marked '= default'
+ // - actually deleted
+ // - not in template instantiation.
+ // We bind the declaration to "method-decl" and also to "constructor" when
+ // it is a constructor.
+
+ Finder->addMatcher(
+ cxxMethodDecl(anyOf(cxxConstructorDecl().bind("constructor"),
+ isCopyAssignmentOperator(),
+ isMoveAssignmentOperator()),
+ isDefaulted(), unless(isImplicit()), isDeleted(),
+ unless(isInstantiated()))
+ .bind("method-decl"),
+ this);
+}
+
+void DeletedDefaultCheck::check(const MatchFinder::MatchResult &Result) {
+ const StringRef Message = "%0 is explicitly defaulted but implicitly "
+ "deleted, probably because %1; definition can "
+ "either be removed or explicitly deleted";
+ if (const auto *Constructor =
+ Result.Nodes.getNodeAs<CXXConstructorDecl>("constructor")) {
+ auto Diag = diag(Constructor->getLocStart(), Message);
+ if (Constructor->isDefaultConstructor()) {
+ Diag << "default constructor"
+ << "a non-static data member or a base class is lacking a default "
+ "constructor";
+ } else if (Constructor->isCopyConstructor()) {
+ Diag << "copy constructor"
+ << "a non-static data member or a base class is not copyable";
+ } else if (Constructor->isMoveConstructor()) {
+ Diag << "move constructor"
+ << "a non-static data member or a base class is neither copyable "
+ "nor movable";
+ }
+ } else if (const auto *Assignment =
+ Result.Nodes.getNodeAs<CXXMethodDecl>("method-decl")) {
+ diag(Assignment->getLocStart(), Message)
+ << (Assignment->isCopyAssignmentOperator() ? "copy assignment operator"
+ : "move assignment operator")
+ << "a base class or a non-static data member is not assignable, e.g. "
+ "because the latter is marked 'const'";
+ }
+}
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
Added: clang-tools-extra/trunk/clang-tidy/readability/DeletedDefaultCheck.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/DeletedDefaultCheck.h?rev=266190&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/readability/DeletedDefaultCheck.h (added)
+++ clang-tools-extra/trunk/clang-tidy/readability/DeletedDefaultCheck.h Wed Apr 13 06:33:40 2016
@@ -0,0 +1,36 @@
+//===--- DeletedDefaultCheck.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_READABILITY_DELETED_DEFAULT_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_DELETED_DEFAULT_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+/// Checks when a constructor or an assignment operator is marked as '= default'
+/// but is actually deleted by the compiler.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/readability-deleted-default.html
+class DeletedDefaultCheck : public ClangTidyCheck {
+public:
+ DeletedDefaultCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_DELETED_DEFAULT_H
Modified: clang-tools-extra/trunk/clang-tidy/readability/ReadabilityTidyModule.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/ReadabilityTidyModule.cpp?rev=266190&r1=266189&r2=266190&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/readability/ReadabilityTidyModule.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/readability/ReadabilityTidyModule.cpp Wed Apr 13 06:33:40 2016
@@ -13,6 +13,7 @@
#include "AvoidConstParamsInDecls.h"
#include "BracesAroundStatementsCheck.h"
#include "ContainerSizeEmptyCheck.h"
+#include "DeletedDefaultCheck.h"
#include "ElseAfterReturnCheck.h"
#include "FunctionSizeCheck.h"
#include "IdentifierNamingCheck.h"
@@ -40,6 +41,8 @@ public:
"readability-braces-around-statements");
CheckFactories.registerCheck<ContainerSizeEmptyCheck>(
"readability-container-size-empty");
+ CheckFactories.registerCheck<DeletedDefaultCheck>(
+ "readability-deleted-default");
CheckFactories.registerCheck<ElseAfterReturnCheck>(
"readability-else-after-return");
CheckFactories.registerCheck<FunctionSizeCheck>(
Modified: clang-tools-extra/trunk/docs/ReleaseNotes.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/ReleaseNotes.rst?rev=266190&r1=266189&r2=266190&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/ReleaseNotes.rst (original)
+++ clang-tools-extra/trunk/docs/ReleaseNotes.rst Wed Apr 13 06:33:40 2016
@@ -154,6 +154,12 @@ identified. The improvements since the
Warns about top-level const parameters in function declarations.
+- New `readability-deleted-default
+ <http://clang.llvm.org/extra/clang-tidy/checks/readability-deleted-default.html>`_ check
+
+ Warns about defaulted constructors and assignment operators that are actually
+ deleted.
+
- New `readability-redundant-control-flow
<http://clang.llvm.org/extra/clang-tidy/checks/readability-redundant-control-flow.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=266190&r1=266189&r2=266190&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst (original)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst Wed Apr 13 06:33:40 2016
@@ -98,6 +98,7 @@ Clang-Tidy Checks
readability-avoid-const-params-in-decls
readability-braces-around-statements
readability-container-size-empty
+ readability-deleted-default
readability-else-after-return
readability-function-size
readability-identifier-naming
Added: clang-tools-extra/trunk/docs/clang-tidy/checks/readability-deleted-default.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/readability-deleted-default.rst?rev=266190&view=auto
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/readability-deleted-default.rst (added)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/readability-deleted-default.rst Wed Apr 13 06:33:40 2016
@@ -0,0 +1,21 @@
+.. title:: clang-tidy - readability-deleted-default
+
+readability-deleted-default
+===========================
+
+Checks that constructors and assignment operators marked as ``= default`` are
+not actually deleted by the compiler.
+
+.. code:: c++
+ class Example {
+ public:
+ // This constructor is deleted because I is missing a default value.
+ Example() = default;
+ // This is fine.
+ Example(const Example& Other) = default;
+ // This operator is deleted because I cannot be assigned (it is const).
+ Example& operator=(const Example& Other) = default;
+ private:
+ const int I;
+ };
+
Added: clang-tools-extra/trunk/test/clang-tidy/readability-deleted-default.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/readability-deleted-default.cpp?rev=266190&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/readability-deleted-default.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/readability-deleted-default.cpp Wed Apr 13 06:33:40 2016
@@ -0,0 +1,127 @@
+// RUN: %check_clang_tidy %s readability-deleted-default %t
+
+class NoDefault {
+public:
+ NoDefault() = delete;
+ NoDefault(NoDefault &&Other) = delete;
+ NoDefault(const NoDefault &Other) = delete;
+};
+
+class MissingEverything {
+public:
+ MissingEverything() = default;
+ // CHECK-MESSAGES: warning: default constructor is explicitly defaulted but implicitly deleted, probably because a non-static data member or a base class is lacking a default constructor; definition can either be removed or explicitly deleted [readability-deleted-default]
+ MissingEverything(MissingEverything &&Other) = default;
+ // CHECK-MESSAGES: warning: move constructor is explicitly defaulted but implicitly deleted, probably because a non-static data member or a base class is neither copyable nor movable; definition can either be removed or explicitly deleted [readability-deleted-default]
+ MissingEverything(const MissingEverything &Other) = default;
+ // CHECK-MESSAGES: warning: copy constructor is explicitly defaulted but implicitly deleted, probably because a non-static data member or a base class is not copyable; definition can either be removed or explicitly deleted [readability-deleted-default]
+ MissingEverything &operator=(MissingEverything &&Other) = default;
+ // CHECK-MESSAGES: warning: move assignment operator is explicitly defaulted but implicitly deleted, probably because a base class or a non-static data member is not assignable, e.g. because the latter is marked 'const'; definition can either be removed or explicitly deleted [readability-deleted-default]
+ MissingEverything &operator=(const MissingEverything &Other) = default;
+ // CHECK-MESSAGES: warning: copy assignment operator is explicitly defaulted but implicitly deleted, probably because a base class or a non-static data member is not assignable, e.g. because the latter is marked 'const'; definition can either be removed or explicitly deleted [readability-deleted-default]
+
+private:
+ NoDefault ND;
+};
+
+class NotAssignable {
+public:
+ NotAssignable(NotAssignable &&Other) = default;
+ NotAssignable(const NotAssignable &Other) = default;
+ NotAssignable &operator=(NotAssignable &&Other) = default;
+ // CHECK-MESSAGES: warning: move assignment operator is explicitly defaulted but implicitly deleted
+ NotAssignable &operator=(const NotAssignable &Other) = default;
+ // CHECK-MESSAGES: warning: copy assignment operator is explicitly defaulted but implicitly deleted
+
+private:
+ const int I = 0;
+};
+
+class Movable {
+public:
+ Movable() = default;
+ Movable(Movable &&Other) = default;
+ Movable(const Movable &Other) = delete;
+ Movable &operator=(Movable &&Other) = default;
+ Movable &operator=(const Movable &Other) = delete;
+};
+
+class NotCopyable {
+public:
+ NotCopyable(NotCopyable &&Other) = default;
+ NotCopyable(const NotCopyable &Other) = default;
+ // CHECK-MESSAGES: warning: copy constructor is explicitly defaulted but implicitly deleted
+ NotCopyable &operator=(NotCopyable &&Other) = default;
+ NotCopyable &operator=(const NotCopyable &Other) = default;
+ // CHECK-MESSAGES: warning: copy assignment operator is explicitly defaulted but implicitly deleted
+private:
+ Movable M;
+};
+
+template <typename T> class Templated {
+public:
+ // No warning here, it is a templated class.
+ Templated() = default;
+ Templated(Templated &&Other) = default;
+ Templated(const Templated &Other) = default;
+ Templated &operator=(Templated &&Other) = default;
+ Templated &operator=(const Templated &Other) = default;
+
+ class InnerTemplated {
+ public:
+ // This class is not in itself templated, but we still don't have warning.
+ InnerTemplated() = default;
+ InnerTemplated(InnerTemplated &&Other) = default;
+ InnerTemplated(const InnerTemplated &Other) = default;
+ InnerTemplated &operator=(InnerTemplated &&Other) = default;
+ InnerTemplated &operator=(const InnerTemplated &Other) = default;
+
+ private:
+ T TVar;
+ };
+
+ class InnerNotTemplated {
+ public:
+ // This one could technically have warnings, but currently doesn't.
+ InnerNotTemplated() = default;
+ InnerNotTemplated(InnerNotTemplated &&Other) = default;
+ InnerNotTemplated(const InnerNotTemplated &Other) = default;
+ InnerNotTemplated &operator=(InnerNotTemplated &&Other) = default;
+ InnerNotTemplated &operator=(const InnerNotTemplated &Other) = default;
+
+ private:
+ int I;
+ };
+
+private:
+ const T TVar{};
+};
+
+int FunctionWithInnerClass() {
+ class InnerNotAssignable {
+ public:
+ InnerNotAssignable &operator=(InnerNotAssignable &&Other) = default;
+ // CHECK-MESSAGES: warning: move assignment operator is explicitly defaulted but implicitly deleted
+ private:
+ const int I = 0;
+ };
+ return 1;
+};
+
+template <typename T>
+int TemplateFunctionWithInnerClass() {
+ class InnerNotAssignable {
+ public:
+ InnerNotAssignable &operator=(InnerNotAssignable &&Other) = default;
+ private:
+ const T TVar{};
+ };
+ return 1;
+};
+
+void Foo() {
+ Templated<const int> V1;
+ Templated<int>::InnerTemplated V2;
+ Templated<float>::InnerNotTemplated V3;
+ TemplateFunctionWithInnerClass<int>();
+}
More information about the cfe-commits
mailing list