Index: clang-tidy/misc/BadExceptionTypeCheck.h =================================================================== --- /dev/null +++ clang-tidy/misc/BadExceptionTypeCheck.h @@ -0,0 +1,33 @@ +//===--- BadExceptionTypeCheck.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_BAD_EXCEPTION_TYPE_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_BAD_EXCEPTION_TYPE_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace misc { + +/// \brief checks for locations that throw an object of inappropriate type. +/// http://clang.llvm.org/extra/clang-tidy/checks/misc-bad-exception-type.html +class BadExceptionTypeCheck : public ClangTidyCheck { +public: + BadExceptionTypeCheck(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_BAD_EXCEPTION_TYPE_H Index: clang-tidy/misc/BadExceptionTypeCheck.cpp =================================================================== --- /dev/null +++ clang-tidy/misc/BadExceptionTypeCheck.cpp @@ -0,0 +1,45 @@ +//===--- BadExceptionTypeCheck.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 "BadExceptionTypeCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace misc { + +void BadExceptionTypeCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + cxxThrowExpr(has(expr(unless(hasType(cxxRecordDecl(allOf( + unless(hasName("::std::basic_string")), + unless(hasName("::std::auto_ptr")), + unless(hasName("::std::unique_ptr")), + unless(hasName("::std::shared_ptr")), + unless(hasName("::std::weak_ptr")) + ))))))) + .bind("throw") + , this); +} + +void BadExceptionTypeCheck::check(const MatchFinder::MatchResult &Result) { + const auto *Throw = Result.Nodes.getNodeAs("throw"); + const auto ExceptionQualType = Throw->getSubExpr()->getType(); + + diag(Throw->getLocStart(), + "the type of the thrown exception (%0) is not appropriate; " + "use a class indicating what happened instead") + << ExceptionQualType.getAsString(); +} + +} // namespace misc +} // namespace tidy +} // namespace clang Index: clang-tidy/misc/CMakeLists.txt =================================================================== --- clang-tidy/misc/CMakeLists.txt +++ clang-tidy/misc/CMakeLists.txt @@ -3,6 +3,7 @@ add_clang_library(clangTidyMiscModule ArgumentCommentCheck.cpp AssertSideEffectCheck.cpp + BadExceptionTypeCheck.cpp ForwardingReferenceOverloadCheck.cpp MisplacedConstCheck.cpp UnconventionalAssignOperatorCheck.cpp Index: clang-tidy/misc/MiscTidyModule.cpp =================================================================== --- clang-tidy/misc/MiscTidyModule.cpp +++ clang-tidy/misc/MiscTidyModule.cpp @@ -12,6 +12,7 @@ #include "../ClangTidyModuleRegistry.h" #include "ArgumentCommentCheck.h" #include "AssertSideEffectCheck.h" +#include "BadExceptionTypeCheck.h" #include "BoolPointerImplicitConversionCheck.h" #include "DanglingHandleCheck.h" #include "DefinitionsInHeadersCheck.h" @@ -66,6 +67,8 @@ CheckFactories.registerCheck("misc-argument-comment"); CheckFactories.registerCheck( "misc-assert-side-effect"); + CheckFactories.registerCheck( + "misc-bad-exception-type"); CheckFactories.registerCheck( "misc-forwarding-reference-overload"); CheckFactories.registerCheck("misc-misplaced-const"); Index: docs/clang-tidy/checks/list.rst =================================================================== --- docs/clang-tidy/checks/list.rst +++ docs/clang-tidy/checks/list.rst @@ -73,6 +73,7 @@ llvm-twine-local misc-argument-comment misc-assert-side-effect + misc-bad-exception-type misc-bool-pointer-implicit-conversion misc-dangling-handle misc-definitions-in-headers Index: docs/clang-tidy/checks/misc-bad-exception-type.rst =================================================================== --- /dev/null +++ docs/clang-tidy/checks/misc-bad-exception-type.rst @@ -0,0 +1,24 @@ +.. title:: clang-tidy - misc-bad-exception-type + +misc-bad-exception-type +======================= + +Checks for exceptions of inappropriate type, +for example string, int or pointer. + +It allows only record types and blacklists some types +from STL. In particular: + +* std::string (and std::basic_string) +* std::auto_ptr +* std::unique_ptr + +See also misc-throw-by-value-catch-by-reference. + +Example: + +.. code-block:: c++ + + throw 42; + throw "42"; + throw std::string("42"); Index: test/clang-tidy/misc-bad-exception-type.cpp =================================================================== --- /dev/null +++ test/clang-tidy/misc-bad-exception-type.cpp @@ -0,0 +1,76 @@ +// RUN: %check_clang_tidy %s misc-bad-exception-type %t + +void throw_int() { + throw 42; +} +// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: the type of the thrown exception (int) is not appropriate; use a class indicating what happened instead [misc-bad-exception-type + +namespace std { + template + class basic_string {}; + + using string = basic_string; + + template + class auto_ptr {}; + + template + class unique_ptr {}; + + template + class shared_ptr {}; + + template + class weak_ptr {}; +} + + +void throw_string() { + throw std::string(); +} +// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: the type of the thrown exception (std::string) is not appropriate; use a class indicating what happened instead [misc-bad-exception-type + +void throw_auto_ptr() { + throw std::auto_ptr(); +} +// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: the type of the thrown exception (std::auto_ptr) is not appropriate; use a class indicating what happened instead [misc-bad-exception-type + +void throw_unique_ptr() { + throw std::unique_ptr(); +} +// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: the type of the thrown exception (std::unique_ptr) is not appropriate; use a class indicating what happened instead [misc-bad-exception-type + +void throw_shared_ptr() { + throw std::shared_ptr(); +} +// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: the type of the thrown exception (std::shared_ptr) is not appropriate; use a class indicating what happened instead [misc-bad-exception-type + +void throw_weak_ptr() { + throw std::weak_ptr(); +} +// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: the type of the thrown exception (std::weak_ptr) is not appropriate; use a class indicating what happened instead [misc-bad-exception-type + + +class A{}; + +void throw_class() { + throw A(); +} + +void throw_pointer_to_class() { + A a; + throw &a; +} +// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: the type of the thrown exception (class A *) is not appropriate; use a class indicating what happened instead [misc-bad-exception-type + + +void throw_pointer_to_int() { + int x; + throw &x; +} +// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: the type of the thrown exception (int *) is not appropriate; use a class indicating what happened instead [misc-bad-exception-type + +void throw_nullptr() { + throw nullptr; +} +// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: the type of the thrown exception (nullptr_t) is not appropriate; use a class indicating what happened instead [misc-bad-exception-type