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>();
47 if (isUnresolvedExceptionSpec(ProtoType->getExceptionSpecType()))
50 switch (ProtoType->getNoexceptSpec(*Result.Context)) {
51 case FunctionProtoType::NR_NoNoexcept:
52 diag(Decl->getLocation(),
"move %0s should be marked noexcept")
56 case FunctionProtoType::NR_Throw:
59 if (
const Expr *E = ProtoType->getNoexceptExpr()) {
60 if (isa<CXXBoolLiteralExpr>(E))
63 "noexcept specifier on the move %0 evaluates to 'false'")
67 case FunctionProtoType::NR_Nothrow:
68 case FunctionProtoType::NR_Dependent:
69 case FunctionProtoType::NR_BadNoexcept:
std::unique_ptr< ast_matchers::MatchFinder > Finder