@@ -72,7 +72,13 @@ void CheckExceptionSafety::destructors()
7272 }
7373}
7474
75-
75+ void CheckExceptionSafety::destructorsError (const Token * const tok, const std::string &className) {
76+ reportError (tok, Severity::warning, " exceptThrowInDestructor" ,
77+ " Class " + className + " is not safe, destructor throws exception\n "
78+ " The class " + className + " is not safe because its destructor "
79+ " throws an exception. If " + className + " is used and an exception "
80+ " is thrown that is caught in an outer scope the program will terminate." , CWE398, Certainty::normal);
81+ }
7682
7783
7884void CheckExceptionSafety::deallocThrow ()
@@ -136,6 +142,11 @@ void CheckExceptionSafety::deallocThrow()
136142 }
137143}
138144
145+ void CheckExceptionSafety::deallocThrowError (const Token * const tok, const std::string &varname) {
146+ reportError (tok, Severity::warning, " exceptDeallocThrow" , " Exception thrown in invalid state, '" +
147+ varname + " ' points at deallocated memory." , CWE398, Certainty::normal);
148+ }
149+
139150// ---------------------------------------------------------------------------
140151// catch(const exception & err)
141152// {
@@ -173,6 +184,13 @@ void CheckExceptionSafety::checkRethrowCopy()
173184 }
174185}
175186
187+ void CheckExceptionSafety::rethrowCopyError (const Token * const tok, const std::string &varname) {
188+ reportError (tok, Severity::style, " exceptRethrowCopy" ,
189+ " Throwing a copy of the caught exception instead of rethrowing the original exception.\n "
190+ " Rethrowing an exception with 'throw " + varname + " ;' creates an unnecessary copy of '" + varname + " '. "
191+ " To rethrow the caught exception without unnecessary copying or slicing, use a bare 'throw;'." , CWE398, Certainty::normal);
192+ }
193+
176194// ---------------------------------------------------------------------------
177195// try {} catch (std::exception err) {} <- Should be "std::exception& err"
178196// ---------------------------------------------------------------------------
@@ -195,6 +213,13 @@ void CheckExceptionSafety::checkCatchExceptionByValue()
195213 }
196214}
197215
216+ void CheckExceptionSafety::catchExceptionByValueError (const Token *tok) {
217+ reportError (tok, Severity::style,
218+ " catchExceptionByValue" , " Exception should be caught by reference.\n "
219+ " The exception is caught by value. It could be caught "
220+ " as a (const) reference which is usually recommended in C++." , CWE398, Certainty::normal);
221+ }
222+
198223
199224static const Token * functionThrowsRecursive (const Function * function, std::set<const Function *> & recursive)
200225{
@@ -273,6 +298,10 @@ void CheckExceptionSafety::nothrowThrows()
273298 }
274299}
275300
301+ void CheckExceptionSafety::noexceptThrowError (const Token * const tok) {
302+ reportError (tok, Severity::error, " throwInNoexceptFunction" , " Exception thrown in function declared not to throw exceptions." , CWE398, Certainty::normal);
303+ }
304+
276305// --------------------------------------------------------------------------
277306// void func() { functionWithExceptionSpecification(); }
278307// --------------------------------------------------------------------------
@@ -305,6 +334,15 @@ void CheckExceptionSafety::unhandledExceptionSpecification()
305334 }
306335}
307336
337+ void CheckExceptionSafety::unhandledExceptionSpecificationError (const Token * const tok1, const Token * const tok2, const std::string & funcname) {
338+ const std::string str1 (tok1 ? tok1->str () : " foo" );
339+ const std::list<const Token*> locationList = { tok1, tok2 };
340+ reportError (locationList, Severity::style, " unhandledExceptionSpecification" ,
341+ " Unhandled exception specification when calling function " + str1 + " ().\n "
342+ " Unhandled exception specification when calling function " + str1 + " (). "
343+ " Either use a try/catch around the function call, or add a exception specification for " + funcname + " () also." , CWE703, Certainty::inconclusive);
344+ }
345+
308346// --------------------------------------------------------------------------
309347// 7.6.18.4 If no exception is presently being handled, evaluating a throw-expression with no operand calls std::terminate().
310348// --------------------------------------------------------------------------
0 commit comments