Index: misc/CMakeLists.txt =================================================================== --- misc/CMakeLists.txt +++ misc/CMakeLists.txt @@ -25,6 +25,7 @@ SuspiciousSemicolonCheck.cpp SwappedArgumentsCheck.cpp ThrowByValueCatchByReferenceCheck.cpp + ThrowWithNoexceptCheck.cpp UndelegatedConstructor.cpp UnusedAliasDeclsCheck.cpp UnusedParametersCheck.cpp Index: misc/MiscTidyModule.cpp =================================================================== --- misc/MiscTidyModule.cpp +++ misc/MiscTidyModule.cpp @@ -33,6 +33,7 @@ #include "SuspiciousSemicolonCheck.h" #include "SwappedArgumentsCheck.h" #include "ThrowByValueCatchByReferenceCheck.h" +#include "ThrowWithNoexceptCheck.h" #include "UndelegatedConstructor.h" #include "UniqueptrResetReleaseCheck.h" #include "UnusedAliasDeclsCheck.h" @@ -91,6 +92,8 @@ "misc-swapped-arguments"); CheckFactories.registerCheck( "misc-throw-by-value-catch-by-reference"); + CheckFactories.registerCheck( + "misc-throw-with-noexcept"); CheckFactories.registerCheck( "misc-undelegated-constructor"); CheckFactories.registerCheck( Index: misc/ThrowWithNoexceptCheck.h =================================================================== --- misc/ThrowWithNoexceptCheck.h +++ misc/ThrowWithNoexceptCheck.h @@ -0,0 +1,33 @@ +//===--- ThrowWithNoexceptCheck.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_THROW_WITH_NOEXCEPT_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_THROW_WITH_NOEXCEPT_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace misc { + +///\brief Warns about using throw in function declared as noexcept. +/// It complains about every throw, even if it is caught later. +class ThrowWithNoexceptCheck : public ClangTidyCheck { +public: + ThrowWithNoexceptCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace misc +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_THROW_WITH_NOEXCEPT_H Index: misc/ThrowWithNoexceptCheck.cpp =================================================================== --- misc/ThrowWithNoexceptCheck.cpp +++ misc/ThrowWithNoexceptCheck.cpp @@ -0,0 +1,33 @@ +//===--- ThrowWithNoexceptCheck.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 "ThrowWithNoexceptCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace misc { + +void ThrowWithNoexceptCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(cxxThrowExpr(stmt(hasAncestor(functionDecl(isNoThrow()).bind("func")))).bind("throw"), this); +} + +void ThrowWithNoexceptCheck::check(const MatchFinder::MatchResult &Result) { + const auto *Function = Result.Nodes.getNodeAs("func"); + const auto *Throw = Result.Nodes.getNodeAs("throw"); + diag(Throw->getLocStart(), "throw in function declared no-throw"); + // FIXME: Add quickfix. It probably should remove noexcept specifier. +} + +} // namespace misc +} // namespace tidy +} // namespace clang