Skip to content

Commit

Permalink
Fix #11031: false positive: exceptThrowInDestructor with destructor d…
Browse files Browse the repository at this point in the history
…eclared noexcept(false) (danmar#6648)
  • Loading branch information
olabetskyi authored Jul 31, 2024
1 parent 53e55be commit d5b4b04
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 7 deletions.
6 changes: 2 additions & 4 deletions lib/checkexceptionsafety.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,8 @@ void CheckExceptionSafety::destructors()
tok = tok->linkAt(1); // end of if ( ... )
tok = tok->linkAt(1); // end of { ... }
}

// throw found within a destructor
else if (tok->str() == "throw") {
else if (tok->str() == "throw" && function->isNoExcept()) {
destructorsError(tok, scope->className);
break;
}
Expand Down Expand Up @@ -296,8 +295,7 @@ void CheckExceptionSafety::nothrowThrows()
continue;

// check noexcept and noexcept(true) functions
if (function->isNoExcept() &&
(!function->noexceptArg || function->noexceptArg->str() == "true")) {
if (function->isNoExcept()) {
const Token *throws = functionThrows(function);
if (throws)
noexceptThrowError(throws);
Expand Down
4 changes: 3 additions & 1 deletion lib/symboldatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2531,8 +2531,10 @@ Function::Function(const Token *tok,
tokenDef->str().size() > scope->className.size() + 1 &&
tokenDef->str()[scope->className.size() + 1] == '<'))) {
// destructor
if (tokenDef->strAt(-1) == "~")
if (tokenDef->strAt(-1) == "~") {
type = Function::eDestructor;
isNoExcept(true);
}
// constructor of any kind
else
type = Function::eConstructor;
Expand Down
15 changes: 13 additions & 2 deletions test/testexceptionsafety.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,17 @@ class TestExceptionSafety : public TestFixture {
" throw e;\n"
" }\n"
"};");
ASSERT_EQUALS("[test.cpp:3]: (warning) Class x is not safe, destructor throws exception\n", errout_str());
ASSERT_EQUALS("[test.cpp:3]: (warning) Class x is not safe, destructor throws exception\n"
"[test.cpp:3]: (error) Exception thrown in function declared not to throw exceptions.\n", errout_str());

check("class x {\n"
" ~x();\n"
"};\n"
"x::~x() {\n"
" throw e;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (warning) Class x is not safe, destructor throws exception\n", errout_str());
ASSERT_EQUALS("[test.cpp:5]: (warning) Class x is not safe, destructor throws exception\n"
"[test.cpp:5]: (error) Exception thrown in function declared not to throw exceptions.\n", errout_str());

// #3858 - throwing exception in try block in destructor.
check("class x {\n"
Expand All @@ -104,6 +106,15 @@ class TestExceptionSafety : public TestFixture {
" }\n"
" }\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (error) Exception thrown in function declared not to throw exceptions.\n", errout_str());

// #11031 should not warn when noexcept false
check("class A {\n"
"public:\n"
" ~A() noexcept(false) {\n"
" throw 30;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout_str());
}

Expand Down

0 comments on commit d5b4b04

Please sign in to comment.