208 lines · cpp
1// RUN: %check_clang_tidy %s bugprone-throw-keyword-missing %t -- -- -fexceptions2 3namespace std {4 5// std::string declaration (taken from test/clang-tidy/readability-redundant-string-cstr-msvc.cpp).6template <typename T>7class allocator {};8template <typename T>9class char_traits {};10template <typename C, typename T = std::char_traits<C>, typename A = std::allocator<C>>11struct basic_string {12 basic_string();13 basic_string(const basic_string &);14 // MSVC headers define two constructors instead of using optional arguments.15 basic_string(const C *);16 basic_string(const C *, const A &);17 ~basic_string();18};19typedef basic_string<char> string;20typedef basic_string<wchar_t> wstring;21 22// std::exception and std::runtime_error declaration.23// CHECK-MESSAGES-DAG: [[#EXCEPTION_LINE:@LINE + 1]]:824struct exception {25 exception();26 exception(const exception &other);27 virtual ~exception();28};29 30struct runtime_error : public exception {31 explicit runtime_error(const std::string &what_arg);32};33 34} // namespace std35 36// The usage of these classes should never emit a warning.37struct RegularClass {};38struct RegularDerived : public RegularClass {};39 40// Class name contains the substring "exception", in certain cases using this class should emit a warning.41struct RegularException {42 RegularException() {}43 44 // Constructors with a single argument are treated differently (cxxFunctionalCastExpr).45 RegularException(int) {}46 47 typedef RegularClass RegularAlias;48};49 50// --------------51 52void stdExceptionNotTrownTest(int i) {53 if (i < 0)54 // CHECK-MESSAGES-DAG: :[[@LINE+1]]:5: warning: suspicious exception object created but not thrown; did you mean 'throw {{.*}}'? [bugprone-throw-keyword-missing]55 std::exception();56 57 if (i > 0)58 // CHECK-MESSAGES-DAG: :[[@LINE+1]]:5: warning: suspicious exception59 std::runtime_error("Unexpected argument");60 // CHECK-MESSAGES: note: object type inherits from base class declared here61}62 63void stdExceptionThrownTest(int i) {64 if (i < 0)65 throw std::exception();66 67 if (i > 0)68 throw std::runtime_error("Unexpected argument");69}70 71void regularClassNotThrownTest(int i) {72 if (i < 0)73 RegularClass();74}75 76void regularClassWithAliasNotThrownTest(int i) {77 RegularDerived();78}79 80void regularClassThrownTest(int i) {81 if (i < 0)82 throw RegularClass();83}84 85void nameContainsExceptionNotThrownTest(int i) {86 if (i < 0)87 // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception88 RegularException();89 90 if (i > 0)91 // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception92 RegularException(5);93}94 95void nameContainsExceptionThrownTest(int i) {96 if (i < 0)97 throw RegularException();98 99 if (i > 0)100 throw RegularException(5);101}102 103template <class Exception>104void f(int i, Exception excToBeThrown) {}105 106template <class SomeType>107void templ(int i) {108 if (i > 0)109 SomeType();110}111 112void funcCallWithTempExcTest() {113 f(5, RegularException());114 115 templ<RegularException>(4);116 templ<RegularClass>(4);117}118 119// Global variable initialization test.120RegularException exc = RegularException();121RegularException *excptr = new RegularException();122 123void localVariableInitTest() {124 RegularException exc = RegularException();125 RegularException *excptr = new RegularException();126}127 128class CtorInitializerListTest {129 RegularException exc;130 RegularException exc2{};131 132 CtorInitializerListTest() : exc(RegularException()) {}133 134 CtorInitializerListTest(int) try : exc(RegularException()) {135 // Constructor body136 } catch (...) {137 // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception138 RegularException();139 }140 141 CtorInitializerListTest(float);142};143 144CtorInitializerListTest::CtorInitializerListTest(float) try : exc(RegularException()) {145 // Constructor body146} catch (...) {147 // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: suspicious exception148 RegularException();149}150 151namespace GH115055 {152class CtorInitializerListTest2 {153 public:154 CtorInitializerListTest2() {}155 private:156 RegularException exc{};157};158} // namespace GH115055159 160RegularException funcReturningExceptionTest(int i) {161 return RegularException();162}163 164void returnedValueTest() {165 funcReturningExceptionTest(3);166}167 168struct ClassBracedInitListTest {169 ClassBracedInitListTest(RegularException exc) {}170};171 172void foo(RegularException, ClassBracedInitListTest) {}173 174void bracedInitListTest() {175 RegularException exc{};176 ClassBracedInitListTest test = {RegularException()};177 foo({}, {RegularException()});178}179 180typedef std::exception ERROR_BASE;181class RegularError : public ERROR_BASE {};182 183void typedefTest() {184 // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: suspicious exception185 RegularError();186 // CHECK-MESSAGES: :[[#EXCEPTION_LINE]]:8: note: object type inherits from base class declared here187}188 189struct ExceptionRAII {190 ExceptionRAII() {}191 ~ExceptionRAII() {}192};193 194void exceptionRAIITest() {195 ExceptionRAII E;196}197 198namespace std {199typedef decltype(sizeof(void*)) size_t;200}201 202void* operator new(std::size_t, void*);203 204void placeMentNewTest() {205 alignas(RegularException) unsigned char expr[sizeof(RegularException)];206 new (expr) RegularException{};207}208