11 #include "clang/AST/ASTContext.h"
12 #include "clang/ASTMatchers/ASTMatchFinder.h"
14 using namespace clang::ast_matchers;
20 void NoexceptMoveConstructorCheck::registerMatchers(MatchFinder *
Finder) {
23 if (!getLangOpts().CPlusPlus11)
27 cxxMethodDecl(anyOf(cxxConstructorDecl(), hasOverloadedOperatorName(
"=")),
28 unless(isImplicit()), unless(isDeleted()))
33 void NoexceptMoveConstructorCheck::check(
34 const MatchFinder::MatchResult &
Result) {
35 if (
const auto *Decl = Result.Nodes.getNodeAs<CXXMethodDecl>(
"decl")) {
36 StringRef MethodType =
"assignment operator";
37 if (
const auto *Ctor = dyn_cast<CXXConstructorDecl>(Decl)) {
38 if (!Ctor->isMoveConstructor())
40 MethodType =
"constructor";
41 }
else if (!Decl->isMoveAssignmentOperator()) {
45 const auto *ProtoType = Decl->getType()->getAs<FunctionProtoType>();
46 switch(ProtoType->getNoexceptSpec(*Result.Context)) {
47 case FunctionProtoType::NR_NoNoexcept:
48 diag(Decl->getLocation(),
"move %0s should be marked noexcept")
52 case FunctionProtoType::NR_Throw:
55 if (
const Expr *E = ProtoType->getNoexceptExpr()) {
56 if (isa<CXXBoolLiteralExpr>(E))
59 "noexcept specifier on the move %0 evaluates to 'false'")
63 case FunctionProtoType::NR_Nothrow:
64 case FunctionProtoType::NR_Dependent:
65 case FunctionProtoType::NR_BadNoexcept:
std::unique_ptr< ast_matchers::MatchFinder > Finder