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