[clang-tools-extra] r268492 - [clang-tidy] New: checker misc-unconventional-assign-operator replacing misc-assign-operator-signature

Gabor Horvath via cfe-commits cfe-commits at lists.llvm.org
Wed May 4 05:02:22 PDT 2016


Author: xazax
Date: Wed May  4 07:02:22 2016
New Revision: 268492

URL: http://llvm.org/viewvc/llvm-project?rev=268492&view=rev
Log:
[clang-tidy] New: checker misc-unconventional-assign-operator replacing misc-assign-operator-signature

Summary: Finds return statements in assign operator bodies where the return value is different from '*this'. Only assignment operators with correct return value Class& are checked.

Reviewers: aaron.ballman, alexfh, sbenza

Subscribers: o.gyorgy, baloghadamsoftware, LegalizeAdulthood, aaron.ballman, Eugene.Zelenko, xazax.hun, cfe-commits

Differential Revision: http://reviews.llvm.org/D18265

Added:
    clang-tools-extra/trunk/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp
    clang-tools-extra/trunk/clang-tidy/misc/UnconventionalAssignOperatorCheck.h
    clang-tools-extra/trunk/docs/clang-tidy/checks/misc-unconventional-assign-operator.rst
    clang-tools-extra/trunk/test/clang-tidy/misc-unconventional-assign-operator.cpp
Removed:
    clang-tools-extra/trunk/clang-tidy/misc/AssignOperatorSignatureCheck.cpp
    clang-tools-extra/trunk/clang-tidy/misc/AssignOperatorSignatureCheck.h
    clang-tools-extra/trunk/docs/clang-tidy/checks/misc-assign-operator-signature.rst
    clang-tools-extra/trunk/test/clang-tidy/misc-assign-operator-signature.cpp
Modified:
    clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
    clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt
    clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.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/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp?rev=268492&r1=268491&r2=268492&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp Wed May  4 07:02:22 2016
@@ -10,7 +10,7 @@
 #include "../ClangTidy.h"
 #include "../ClangTidyModule.h"
 #include "../ClangTidyModuleRegistry.h"
-#include "../misc/AssignOperatorSignatureCheck.h"
+#include "../misc/UnconventionalAssignOperatorCheck.h"
 #include "InterfacesGlobalInitCheck.h"
 #include "ProBoundsArrayToPointerDecayCheck.h"
 #include "ProBoundsConstantArrayIndexCheck.h"
@@ -53,7 +53,7 @@ public:
         "cppcoreguidelines-pro-type-union-access");
     CheckFactories.registerCheck<ProTypeVarargCheck>(
         "cppcoreguidelines-pro-type-vararg");
-    CheckFactories.registerCheck<misc::AssignOperatorSignatureCheck>(
+    CheckFactories.registerCheck<misc::UnconventionalAssignOperatorCheck>(
         "cppcoreguidelines-c-copy-assignment-signature");
   }
 };

Removed: clang-tools-extra/trunk/clang-tidy/misc/AssignOperatorSignatureCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/AssignOperatorSignatureCheck.cpp?rev=268491&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/AssignOperatorSignatureCheck.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/misc/AssignOperatorSignatureCheck.cpp (removed)
@@ -1,80 +0,0 @@
-//===--- AssignOperatorSignatureCheck.cpp - clang-tidy ----------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "AssignOperatorSignatureCheck.h"
-#include "clang/ASTMatchers/ASTMatchFinder.h"
-#include "clang/ASTMatchers/ASTMatchers.h"
-
-using namespace clang::ast_matchers;
-
-namespace clang {
-namespace tidy {
-namespace misc {
-
-void AssignOperatorSignatureCheck::registerMatchers(
-    ast_matchers::MatchFinder *Finder) {
-  // Only register the matchers for C++; the functionality currently does not
-  // provide any benefit to other languages, despite being benign.
-  if (!getLangOpts().CPlusPlus)
-    return;
-
-  const auto HasGoodReturnType = cxxMethodDecl(returns(
-      lValueReferenceType(pointee(unless(isConstQualified()),
-                                  hasDeclaration(equalsBoundNode("class"))))));
-
-  const auto IsSelf = qualType(
-      anyOf(hasDeclaration(equalsBoundNode("class")),
-            referenceType(pointee(hasDeclaration(equalsBoundNode("class"))))));
-  const auto IsAssign =
-      cxxMethodDecl(unless(anyOf(isDeleted(), isPrivate(), isImplicit())),
-                    hasName("operator="), ofClass(recordDecl().bind("class")))
-          .bind("method");
-  const auto IsSelfAssign =
-      cxxMethodDecl(IsAssign, hasParameter(0, parmVarDecl(hasType(IsSelf))))
-          .bind("method");
-
-  Finder->addMatcher(
-      cxxMethodDecl(IsAssign, unless(HasGoodReturnType)).bind("ReturnType"),
-      this);
-
-  const auto BadSelf = referenceType(
-      anyOf(lValueReferenceType(pointee(unless(isConstQualified()))),
-            rValueReferenceType(pointee(isConstQualified()))));
-
-  Finder->addMatcher(
-      cxxMethodDecl(IsSelfAssign,
-                    hasParameter(0, parmVarDecl(hasType(BadSelf))))
-          .bind("ArgumentType"),
-      this);
-
-  Finder->addMatcher(
-      cxxMethodDecl(IsSelfAssign, anyOf(isConst(), isVirtual())).bind("cv"),
-      this);
-}
-
-void AssignOperatorSignatureCheck::check(
-    const MatchFinder::MatchResult &Result) {
-  const auto *Method = Result.Nodes.getNodeAs<CXXMethodDecl>("method");
-  std::string Name = Method->getParent()->getName();
-
-  static const char *const Messages[][2] = {
-      {"ReturnType", "operator=() should return '%0&'"},
-      {"ArgumentType", "operator=() should take '%0 const&', '%0&&' or '%0'"},
-      {"cv", "operator=() should not be marked '%1'"}};
-
-  for (const auto &Message : Messages) {
-    if (Result.Nodes.getNodeAs<Decl>(Message[0]))
-      diag(Method->getLocStart(), Message[1])
-          << Name << (Method->isConst() ? "const" : "virtual");
-  }
-}
-
-} // namespace misc
-} // namespace tidy
-} // namespace clang

Removed: clang-tools-extra/trunk/clang-tidy/misc/AssignOperatorSignatureCheck.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/AssignOperatorSignatureCheck.h?rev=268491&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/AssignOperatorSignatureCheck.h (original)
+++ clang-tools-extra/trunk/clang-tidy/misc/AssignOperatorSignatureCheck.h (removed)
@@ -1,37 +0,0 @@
-//===--- AssignOperatorSignatureCheck.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_MISC_ASSIGNOPERATORSIGNATURECHECK_H
-#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_ASSIGNOPERATORSIGNATURECHECK_H
-
-#include "../ClangTidy.h"
-
-namespace clang {
-namespace tidy {
-namespace misc {
-
-/// Finds declarations of assign operators with the wrong return and/or argument
-/// types.
-///
-///   * The return type must be `Class&`.
-///   * Works with move-assign and assign by value.
-///   * Private and deleted operators are ignored.
-class AssignOperatorSignatureCheck : public ClangTidyCheck {
-public:
-  AssignOperatorSignatureCheck(StringRef Name, ClangTidyContext *Context)
-      : ClangTidyCheck(Name, Context) {}
-  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
-  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
-};
-
-} // namespace misc
-} // namespace tidy
-} // namespace clang
-
-#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_ASSIGNOPERATORSIGNATURECHECK_H

Modified: clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt?rev=268492&r1=268491&r2=268492&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt Wed May  4 07:02:22 2016
@@ -3,7 +3,7 @@ set(LLVM_LINK_COMPONENTS support)
 add_clang_library(clangTidyMiscModule
   ArgumentCommentCheck.cpp
   AssertSideEffectCheck.cpp
-  AssignOperatorSignatureCheck.cpp
+  UnconventionalAssignOperatorCheck.cpp
   BoolPointerImplicitConversionCheck.cpp
   DanglingHandleCheck.cpp
   DefinitionsInHeadersCheck.cpp

Modified: clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp?rev=268492&r1=268491&r2=268492&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp Wed May  4 07:02:22 2016
@@ -12,7 +12,7 @@
 #include "../ClangTidyModuleRegistry.h"
 #include "ArgumentCommentCheck.h"
 #include "AssertSideEffectCheck.h"
-#include "AssignOperatorSignatureCheck.h"
+#include "UnconventionalAssignOperatorCheck.h"
 #include "BoolPointerImplicitConversionCheck.h"
 #include "DanglingHandleCheck.h"
 #include "DefinitionsInHeadersCheck.h"
@@ -61,8 +61,8 @@ public:
     CheckFactories.registerCheck<ArgumentCommentCheck>("misc-argument-comment");
     CheckFactories.registerCheck<AssertSideEffectCheck>(
         "misc-assert-side-effect");
-    CheckFactories.registerCheck<AssignOperatorSignatureCheck>(
-        "misc-assign-operator-signature");
+    CheckFactories.registerCheck<UnconventionalAssignOperatorCheck>(
+        "misc-unconventional-assign-operator");
     CheckFactories.registerCheck<BoolPointerImplicitConversionCheck>(
         "misc-bool-pointer-implicit-conversion");
     CheckFactories.registerCheck<DanglingHandleCheck>(

Added: clang-tools-extra/trunk/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp?rev=268492&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp (added)
+++ clang-tools-extra/trunk/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp Wed May  4 07:02:22 2016
@@ -0,0 +1,89 @@
+//===--- UnconventionalUnconventionalAssignOperatorCheck.cpp - clang-tidy -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "UnconventionalAssignOperatorCheck.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+void UnconventionalAssignOperatorCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
+  // Only register the matchers for C++; the functionality currently does not
+  // provide any benefit to other languages, despite being benign.
+  if (!getLangOpts().CPlusPlus)
+    return;
+
+  const auto HasGoodReturnType = cxxMethodDecl(returns(
+      lValueReferenceType(pointee(unless(isConstQualified()),
+                                  hasDeclaration(equalsBoundNode("class"))))));
+
+  const auto IsSelf = qualType(
+      anyOf(hasDeclaration(equalsBoundNode("class")),
+            referenceType(pointee(hasDeclaration(equalsBoundNode("class"))))));
+  const auto IsAssign =
+      cxxMethodDecl(unless(anyOf(isDeleted(), isPrivate(), isImplicit())),
+                    hasName("operator="), ofClass(recordDecl().bind("class")))
+          .bind("method");
+  const auto IsSelfAssign =
+      cxxMethodDecl(IsAssign, hasParameter(0, parmVarDecl(hasType(IsSelf))))
+          .bind("method");
+
+  Finder->addMatcher(
+      cxxMethodDecl(IsAssign, unless(HasGoodReturnType)).bind("ReturnType"),
+      this);
+
+  const auto BadSelf = referenceType(
+      anyOf(lValueReferenceType(pointee(unless(isConstQualified()))),
+            rValueReferenceType(pointee(isConstQualified()))));
+
+  Finder->addMatcher(
+      cxxMethodDecl(IsSelfAssign,
+                    hasParameter(0, parmVarDecl(hasType(BadSelf))))
+          .bind("ArgumentType"),
+      this);
+
+  Finder->addMatcher(
+      cxxMethodDecl(IsSelfAssign, anyOf(isConst(), isVirtual())).bind("cv"),
+      this);
+
+  const auto IsBadReturnStatement = returnStmt(unless(has(
+      unaryOperator(hasOperatorName("*"), hasUnaryOperand(cxxThisExpr())))));
+  const auto IsGoodAssign = cxxMethodDecl(IsAssign, HasGoodReturnType);
+
+  Finder->addMatcher(returnStmt(IsBadReturnStatement, forFunction(IsGoodAssign))
+                         .bind("returnStmt"),
+                     this);
+}
+
+void UnconventionalAssignOperatorCheck::check(const MatchFinder::MatchResult &Result) {
+  if (const auto *RetStmt = Result.Nodes.getNodeAs<ReturnStmt>("returnStmt")) {
+    diag(RetStmt->getLocStart(), "operator=() should always return '*this'");
+  } else {
+    static const char *const Messages[][2] = {
+        {"ReturnType", "operator=() should return '%0&'"},
+        {"ArgumentType", "operator=() should take '%0 const&', '%0&&' or '%0'"},
+        {"cv", "operator=() should not be marked '%1'"}};
+
+    const auto *Method = Result.Nodes.getNodeAs<CXXMethodDecl>("method");
+    for (const auto &Message : Messages) {
+      if (Result.Nodes.getNodeAs<Decl>(Message[0]))
+        diag(Method->getLocStart(), Message[1])
+            << Method->getParent()->getName()
+            << (Method->isConst() ? "const" : "virtual");
+    }
+  }
+}
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang

Added: clang-tools-extra/trunk/clang-tidy/misc/UnconventionalAssignOperatorCheck.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/UnconventionalAssignOperatorCheck.h?rev=268492&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/UnconventionalAssignOperatorCheck.h (added)
+++ clang-tools-extra/trunk/clang-tidy/misc/UnconventionalAssignOperatorCheck.h Wed May  4 07:02:22 2016
@@ -0,0 +1,42 @@
+//===--- UnconventionalUnconventionalAssignOperatorCheck.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_MISC_ASSIGNOPERATORSIGNATURECHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_ASSIGNOPERATORSIGNATURECHECK_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+/// Finds declarations of assignment operators with the wrong return and/or
+/// argument types and definitions with good return type but wrong return
+/// statements.
+///
+///   * The return type must be `Class&`.
+///   * Works with move-assign and assign by value.
+///   * Private and deleted operators are ignored.
+///   * The operator must always return ``*this``.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/misc-unconventional-assign-operator.html
+class UnconventionalAssignOperatorCheck : public ClangTidyCheck {
+public:
+  UnconventionalAssignOperatorCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_ASSIGNOPERATORSIGNATURECHECK_H

Modified: clang-tools-extra/trunk/docs/ReleaseNotes.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/ReleaseNotes.rst?rev=268492&r1=268491&r2=268492&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/ReleaseNotes.rst (original)
+++ clang-tools-extra/trunk/docs/ReleaseNotes.rst Wed May  4 07:02:22 2016
@@ -236,6 +236,12 @@ identified.  The improvements since the
 
   Finds static function and variable definitions in anonymous namespace.
 
+- New `misc-unconventional-assign-operator
+  <http://clang.llvm.org/extra/clang-tidy/checks/misc-unconventional-assign-operator.html>`_ check replacing old `misc-assign-operator-signature` check
+
+  Does not only checks for correct signature but also for correct ``return``
+  statements (returning ``*this``)
+
 Fixed bugs:
 
 - Crash when running on compile database with relative source files paths.

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=268492&r1=268491&r2=268492&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst (original)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst Wed May  4 07:02:22 2016
@@ -52,7 +52,7 @@ Clang-Tidy Checks
    llvm-twine-local
    misc-argument-comment
    misc-assert-side-effect
-   misc-assign-operator-signature
+   misc-unconventional-assign-operator
    misc-bool-pointer-implicit-conversion
    misc-dangling-handle
    misc-definitions-in-headers

Removed: clang-tools-extra/trunk/docs/clang-tidy/checks/misc-assign-operator-signature.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/misc-assign-operator-signature.rst?rev=268491&view=auto
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/misc-assign-operator-signature.rst (original)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/misc-assign-operator-signature.rst (removed)
@@ -1,12 +0,0 @@
-.. title:: clang-tidy - misc-assign-operator-signature
-
-misc-assign-operator-signature
-==============================
-
-
-Finds declarations of assign operators with the wrong return and/or argument
-types.
-
-  * The return type must be ``Class&``.
-  * Works with move-assign and assign by value.
-  * Private and deleted operators are ignored.

Added: clang-tools-extra/trunk/docs/clang-tidy/checks/misc-unconventional-assign-operator.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/misc-unconventional-assign-operator.rst?rev=268492&view=auto
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/misc-unconventional-assign-operator.rst (added)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/misc-unconventional-assign-operator.rst Wed May  4 07:02:22 2016
@@ -0,0 +1,13 @@
+.. title:: clang-tidy - misc-unconventional-assign-operator
+
+misc-unconventional-assign-operator
+====================
+
+
+Finds declarations of assign operators with the wrong return and/or argument
+types and definitions with good return type but wrong return statements.
+
+  * The return type must be ``Class&``.
+  * Works with move-assign and assign by value.
+  * Private and deleted operators are ignored.
+  * The operator must always return ``*this``.

Removed: clang-tools-extra/trunk/test/clang-tidy/misc-assign-operator-signature.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/misc-assign-operator-signature.cpp?rev=268491&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/misc-assign-operator-signature.cpp (original)
+++ clang-tools-extra/trunk/test/clang-tidy/misc-assign-operator-signature.cpp (removed)
@@ -1,58 +0,0 @@
-// RUN: %check_clang_tidy %s misc-assign-operator-signature %t
-
-struct Good {
-  Good& operator=(const Good&);
-  Good& operator=(Good&&);
-
-  // Assign from other types is fine too.
-  Good& operator=(int);
-};
-
-struct AlsoGood {
-  // By value is also fine.
-  AlsoGood& operator=(AlsoGood);
-};
-
-struct BadReturn {
-  void operator=(const BadReturn&);
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'BadReturn&' [misc-assign-operator-signature]
-  const BadReturn& operator=(BadReturn&&);
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad
-  void operator=(int);
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad
-};
-struct BadReturn2 {
-  BadReturn2&& operator=(const BadReturn2&);
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad
-  int operator=(BadReturn2&&);
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad
-};
-
-struct BadArgument {
-  BadArgument& operator=(BadArgument&);
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should take 'BadArgument const&', 'BadArgument&&' or 'BadArgument'
-  BadArgument& operator=(const BadArgument&&);
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should take 'BadAr
-};
-
-struct BadModifier {
-  BadModifier& operator=(const BadModifier&) const;
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should not be marked 'const'
-};
-
-struct Deleted {
-  // We don't check the return value of deleted operators.
-  void operator=(const Deleted&) = delete;
-  void operator=(Deleted&&) = delete;
-};
-
-class Private {
-  // We don't check the return value of private operators.
-  // Pre-C++11 way of disabling assignment.
-  void operator=(const Private &);
-};
-
-struct Virtual {
-  virtual Virtual& operator=(const Virtual &);
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should not be marked 'virtual'
-};

Added: clang-tools-extra/trunk/test/clang-tidy/misc-unconventional-assign-operator.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/misc-unconventional-assign-operator.cpp?rev=268492&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/misc-unconventional-assign-operator.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/misc-unconventional-assign-operator.cpp Wed May  4 07:02:22 2016
@@ -0,0 +1,79 @@
+// RUN: %check_clang_tidy %s misc-unconventional-assign-operator %t -- -- -std=c++11 -isystem %S/Inputs/Headers
+
+#include <utility>
+
+struct Good {
+  Good& operator=(const Good&);
+  Good& operator=(Good&&);
+
+  // Assign from other types is fine too.
+  Good& operator=(int);
+};
+
+struct AlsoGood {
+  // By value is also fine.
+  AlsoGood& operator=(AlsoGood);
+};
+
+struct BadReturnType {
+  void operator=(const BadReturnType&);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'BadReturnType&' [misc-unconventional-assign-operator]
+  const BadReturnType& operator=(BadReturnType&&);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad
+  void operator=(int);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad
+};
+
+struct BadReturnType2 {
+  BadReturnType2&& operator=(const BadReturnType2&);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad
+  int operator=(BadReturnType2&&);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad
+};
+
+struct BadArgument {
+  BadArgument& operator=(BadArgument&);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should take 'BadArgument const&', 'BadArgument&&' or 'BadArgument'
+  BadArgument& operator=(const BadArgument&&);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should take 'BadAr
+};
+
+struct BadModifier {
+  BadModifier& operator=(const BadModifier&) const;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should not be marked 'const'
+};
+
+struct Deleted {
+  // We don't check the return value of deleted operators.
+  void operator=(const Deleted&) = delete;
+  void operator=(Deleted&&) = delete;
+};
+
+class Private {
+  // We don't check the return value of private operators.
+  // Pre-C++11 way of disabling assignment.
+  void operator=(const Private &);
+};
+
+struct Virtual {
+  virtual Virtual& operator=(const Virtual &);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should not be marked 'virtual'
+};
+
+class BadReturnStatement {
+  int n;
+
+public:
+  BadReturnStatement& operator=(BadReturnStatement&& rhs) {
+    n = std::move(rhs.n);
+    return rhs;
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: operator=() should always return '*this'
+  }
+
+  // Do not check if return type is different from '&BadReturnStatement'
+  int operator=(int i) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad
+    n = i;
+    return n;
+  }
+};




More information about the cfe-commits mailing list