summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clang-tidy/misc/NoexceptMoveCtorsCheck.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/clang-tidy/misc/NoexceptMoveCtorsCheck.cpp')
-rw-r--r--clang-tools-extra/clang-tidy/misc/NoexceptMoveCtorsCheck.cpp65
1 files changed, 65 insertions, 0 deletions
diff --git a/clang-tools-extra/clang-tidy/misc/NoexceptMoveCtorsCheck.cpp b/clang-tools-extra/clang-tidy/misc/NoexceptMoveCtorsCheck.cpp
new file mode 100644
index 00000000000..3b74b8a2ae5
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/misc/NoexceptMoveCtorsCheck.cpp
@@ -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
+
OpenPOWER on IntegriCloud