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) {} +}; _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
