[clang-tools-extra] r238013 - Add a clang-tidy check for move constructors/assignment ops without noexcept.

Alexander Kornienko alexfh at google.com
Fri May 22 03:31:17 PDT 2015


Author: alexfh
Date: Fri May 22 05:31:17 2015
New Revision: 238013

URL: http://llvm.org/viewvc/llvm-project?rev=238013&view=rev
Log:
Add a clang-tidy check for move constructors/assignment ops without noexcept.

Summary:
Add a clang-tidy check (misc-noexcept-move-ctors) for move constructors
and assignment operators not using noexcept.

http://llvm.org/PR23519

Reviewers: klimek

Reviewed By: klimek

Subscribers: curdeius, cfe-commits

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

Added:
    clang-tools-extra/trunk/clang-tidy/misc/NoexceptMoveCtorsCheck.cpp
    clang-tools-extra/trunk/clang-tidy/misc/NoexceptMoveCtorsCheck.h
    clang-tools-extra/trunk/test/clang-tidy/misc-noexcept-move-ctors.cpp
Modified:
    clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt
    clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp

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=238013&r1=238012&r2=238013&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt Fri May 22 05:31:17 2015
@@ -8,6 +8,7 @@ add_clang_library(clangTidyMiscModule
   InaccurateEraseCheck.cpp
   InefficientAlgorithmCheck.cpp
   MiscTidyModule.cpp
+  NoexceptMoveCtorsCheck.cpp
   StaticAssertCheck.cpp
   SwappedArgumentsCheck.cpp
   UndelegatedConstructor.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=238013&r1=238012&r2=238013&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp Fri May 22 05:31:17 2015
@@ -16,6 +16,7 @@
 #include "BoolPointerImplicitConversionCheck.h"
 #include "InaccurateEraseCheck.h"
 #include "InefficientAlgorithmCheck.h"
+#include "NoexceptMoveCtorsCheck.h"
 #include "StaticAssertCheck.h"
 #include "SwappedArgumentsCheck.h"
 #include "UndelegatedConstructor.h"
@@ -41,6 +42,8 @@ public:
         "misc-inaccurate-erase");
     CheckFactories.registerCheck<InefficientAlgorithmCheck>(
         "misc-inefficient-algorithm");
+    CheckFactories.registerCheck<NoexceptMoveCtorsCheck>(
+        "misc-noexcept-move-ctors");
     CheckFactories.registerCheck<StaticAssertCheck>(
         "misc-static-assert");
     CheckFactories.registerCheck<SwappedArgumentsCheck>(

Added: clang-tools-extra/trunk/clang-tidy/misc/NoexceptMoveCtorsCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/NoexceptMoveCtorsCheck.cpp?rev=238013&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/NoexceptMoveCtorsCheck.cpp (added)
+++ clang-tools-extra/trunk/clang-tidy/misc/NoexceptMoveCtorsCheck.cpp Fri May 22 05:31:17 2015
@@ -0,0 +1,65 @@
+//===--- NoexceptMoveCtorsCheck.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 "NoexceptMoveCtorsCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+
+void NoexceptMoveCtorsCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+      methodDecl(anyOf(constructorDecl(), hasOverloadedOperatorName("=")))
+          .bind("decl"),
+      this);
+}
+
+void NoexceptMoveCtorsCheck::check(const MatchFinder::MatchResult &Result) {
+  if (const auto *Decl = Result.Nodes.getNodeAs<CXXMethodDecl>("decl")) {
+    StringRef MethodType = "assignment operator";
+    if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(Decl)) {
+      if (!Ctor->isMoveConstructor())
+        return;
+      MethodType = "constructor";
+    } else if (!Decl->isMoveAssignmentOperator()) {
+      return;
+    }
+
+    const auto *ProtoType = Decl->getType()->getAs<FunctionProtoType>();
+    switch(ProtoType->getNoexceptSpec(*Result.Context)) {
+      case  FunctionProtoType::NR_NoNoexcept:
+        diag(Decl->getLocation(), "move %0s should be marked noexcept")
+            << MethodType;
+        // FIXME: Add a fixit.
+        break;
+      case FunctionProtoType::NR_Throw:
+        // Don't complain about nothrow(false), but complain on nothrow(expr)
+        // where expr evaluates to false.
+        if (const Expr *E = ProtoType->getNoexceptExpr()) {
+          if (isa<CXXBoolLiteralExpr>(E))
+            break;
+          diag(E->getExprLoc(),
+               "noexcept specifier on the move %0 evaluates to 'false'")
+              << MethodType;
+        }
+        break;
+      case FunctionProtoType::NR_Nothrow:
+      case FunctionProtoType::NR_Dependent:
+      case FunctionProtoType::NR_BadNoexcept:
+        break;
+    }
+  }
+}
+
+} // namespace tidy
+} // namespace clang
+

Added: clang-tools-extra/trunk/clang-tidy/misc/NoexceptMoveCtorsCheck.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/NoexceptMoveCtorsCheck.h?rev=238013&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/NoexceptMoveCtorsCheck.h (added)
+++ clang-tools-extra/trunk/clang-tidy/misc/NoexceptMoveCtorsCheck.h Fri May 22 05:31:17 2015
@@ -0,0 +1,37 @@
+//===--- NoexceptMoveCtorsCheck.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_NOEXCEPT_MOVE_CTORS_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NOEXCEPT_MOVE_CTORS_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+
+/// \brief The check flags move constructors and assignment operators not marked
+/// with \c noexcept or marked with \c noexcept(expr) where \c expr evaluates to
+/// \c false (but is not a \c false literal itself).
+///
+/// Move constructors of all the types used with STL containers, for example,
+/// need to be declared \c noexcept. Otherwise STL will choose copy constructors
+/// instead. The same is valid for move assignment operations.
+class NoexceptMoveCtorsCheck : public ClangTidyCheck {
+public:
+  NoexceptMoveCtorsCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NOEXCEPT_MOVE_CTORS_H
+

Added: clang-tools-extra/trunk/test/clang-tidy/misc-noexcept-move-ctors.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/misc-noexcept-move-ctors.cpp?rev=238013&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/misc-noexcept-move-ctors.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/misc-noexcept-move-ctors.cpp Fri May 22 05:31:17 2015
@@ -0,0 +1,37 @@
+// RUN: $(dirname %s)/check_clang_tidy.sh %s misc-noexcept-move-ctors %t
+// REQUIRES: shell
+
+class A {
+  A(A &&);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: move constructors should be marked noexcept [misc-noexcept-move-ctors]
+  A &operator=(A &&);
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: move assignment operators should
+};
+
+struct B {
+  static constexpr bool kFalse = false;
+  B(B &&) noexcept(kFalse);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: noexcept specifier on the move constructor evaluates to 'false' [misc-noexcept-move-ctors]
+};
+
+class OK1 {
+ public:
+  OK1();
+  OK1(const OK1 &);
+  OK1(OK1&&) noexcept;
+  OK1 &operator=(OK1 &&) noexcept;
+  void f();
+  void g() noexcept;
+};
+
+class OK2 {
+  static constexpr bool kTrue = true;
+
+public:
+  OK2(OK2 &&) noexcept(true) {}
+  OK2 &operator=(OK2 &&) noexcept(kTrue) { return *this; }
+};
+
+struct OK3 {
+  OK3(OK3 &&) noexcept(false) {}
+};





More information about the cfe-commits mailing list