From f6f8dc1b81a320e0cd8f130f1635a679f19997af Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 14 Oct 2025 10:13:51 +0200 Subject: [PATCH 1/8] Update checkexceptionsafety.cpp --- lib/checkexceptionsafety.cpp | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/lib/checkexceptionsafety.cpp b/lib/checkexceptionsafety.cpp index 3d93ce6042e..6904234d5f4 100644 --- a/lib/checkexceptionsafety.cpp +++ b/lib/checkexceptionsafety.cpp @@ -296,26 +296,34 @@ void CheckExceptionSafety::nothrowThrows() if (!function) continue; + bool isNoExcept = false, isEntryPoint = false; + // check noexcept and noexcept(true) functions if (function->isNoExcept()) { - const Token *throws = functionThrows(function); - if (throws) - noexceptThrowError(throws); + isNoExcept = true; } // check throw() functions else if (function->isThrow() && !function->throwArg) { - const Token *throws = functionThrows(function); - if (throws) - noexceptThrowError(throws); + isNoExcept = true; } // check __attribute__((nothrow)) or __declspec(nothrow) functions else if (function->isAttributeNothrow()) { - const Token *throws = functionThrows(function); - if (throws) + isNoExcept = true; + } + else if (mSettings->library.isentrypoint(function->name())) { + isEntryPoint = true; + } + if (!isNoExcept && !isEntryPoint) + continue; + if (const Token* throws = functionThrows(function)) { + if (isEntryPoint) + entryPointThrowError(throws); + else noexceptThrowError(throws); } + } } @@ -324,6 +332,11 @@ void CheckExceptionSafety::noexceptThrowError(const Token * const tok) reportError(tok, Severity::error, "throwInNoexceptFunction", "Exception thrown in function declared not to throw exceptions.", CWE398, Certainty::normal); } +void CheckExceptionSafety::entryPointThrowError(const Token * const tok) +{ + reportError(tok, Severity::error, "throwInEntryPoint", "Exception thrown in function that is an entry point.", CWE398, Certainty::normal); +} + //-------------------------------------------------------------------------- // void func() { functionWithExceptionSpecification(); } //-------------------------------------------------------------------------- From 260532bc12e6f89c701351ee2a691ee4df35105f Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 14 Oct 2025 10:14:17 +0200 Subject: [PATCH 2/8] Update checkexceptionsafety.h --- lib/checkexceptionsafety.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/checkexceptionsafety.h b/lib/checkexceptionsafety.h index 37b8ddf3a33..7c5a52b5605 100644 --- a/lib/checkexceptionsafety.h +++ b/lib/checkexceptionsafety.h @@ -82,6 +82,7 @@ class CPPCHECKLIB CheckExceptionSafety : public Check { void rethrowCopyError(const Token * tok, const std::string &varname); void catchExceptionByValueError(const Token *tok); void noexceptThrowError(const Token * tok); + void entryPointThrowError(const Token * tok); /** Missing exception specification */ void unhandledExceptionSpecificationError(const Token * tok1, const Token * tok2, const std::string & funcname); /** Rethrow without currently handled exception */ From 999350fcd06ac187794fde2ab1a6d61287d656c7 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 14 Oct 2025 10:14:51 +0200 Subject: [PATCH 3/8] Update testexceptionsafety.cpp --- test/testexceptionsafety.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/test/testexceptionsafety.cpp b/test/testexceptionsafety.cpp index 0ec92c982e7..12ba2ae59ba 100644 --- a/test/testexceptionsafety.cpp +++ b/test/testexceptionsafety.cpp @@ -57,6 +57,7 @@ class TestExceptionSafety : public TestFixture { TEST_CASE(rethrowNoCurrentException2); TEST_CASE(rethrowNoCurrentException3); TEST_CASE(noFunctionCall); + TEST_CASE(entryPoint); } struct CheckOptions @@ -404,7 +405,7 @@ class TestExceptionSafety : public TestFixture { "{\n" " f();\n" "}\n", dinit(CheckOptions, $.inconclusive = true)); - ASSERT_EQUALS("", errout_str()); + ASSERT_EQUALS("[test.cpp:4:5]: (error) Exception thrown in function that is an entry point. [throwInEntryPoint]\n", errout_str()); } void unhandledExceptionSpecification3() { @@ -421,12 +422,16 @@ class TestExceptionSafety : public TestFixture { "}\n"; check(code, dinit(CheckOptions, $.inconclusive = true)); - ASSERT_EQUALS("[test.cpp:3:5] -> [test.cpp:1:6]: (style, inconclusive) Unhandled exception specification when calling function f(). [unhandledExceptionSpecification]\n" + ASSERT_EQUALS("[test.cpp:10:5]: (error) Exception thrown in function that is an entry point. [throwInEntryPoint]\n" + "[test.cpp:3:5] -> [test.cpp:1:6]: (style, inconclusive) Unhandled exception specification when calling function f(). [unhandledExceptionSpecification]\n" "[test.cpp:6:5] -> [test.cpp:1:6]: (style, inconclusive) Unhandled exception specification when calling function f(). [unhandledExceptionSpecification]\n", errout_str()); const Settings s = settingsBuilder().library("gnu.cfg").build(); check(code, dinit(CheckOptions, $.inconclusive = true, $.s = &s)); - ASSERT_EQUALS("", errout_str()); + ASSERT_EQUALS("[test.cpp:3:5]: (error) Exception thrown in function that is an entry point. [throwInEntryPoint]\n" + "[test.cpp:6:5]: (error) Exception thrown in function that is an entry point. [throwInEntryPoint]\n" + "[test.cpp:10:5]: (error) Exception thrown in function that is an entry point. [throwInEntryPoint]\n", + errout_str()); } void nothrowAttributeThrow() { @@ -490,6 +495,18 @@ class TestExceptionSafety : public TestFixture { "}\n"); ASSERT_EQUALS("", errout_str()); } + + void entryPoint() { + check("void f(int i) {\n" // #14195 + " if (i < 2)\n" + " throw 0;\n" + "}\n" + "int main(int argc, char* argv[]) {\n" + " f(argc);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:6:5]: (error) Exception thrown in function that is an entry point. [throwInEntryPoint]\n", + errout_str()); + } }; REGISTER_TEST(TestExceptionSafety) From a5e9287a90285181c12b7a1063938841fa3b369f Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 14 Oct 2025 10:17:46 +0200 Subject: [PATCH 4/8] Update checkexceptionsafety.cpp --- lib/checkexceptionsafety.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/checkexceptionsafety.cpp b/lib/checkexceptionsafety.cpp index 6904234d5f4..fbdc55fc5b9 100644 --- a/lib/checkexceptionsafety.cpp +++ b/lib/checkexceptionsafety.cpp @@ -446,6 +446,7 @@ void CheckExceptionSafety::getErrorMessages(ErrorLogger *errorLogger, const Sett c.rethrowCopyError(nullptr, "varname"); c.catchExceptionByValueError(nullptr); c.noexceptThrowError(nullptr); + c.entryPointThrowError(nullptr); c.unhandledExceptionSpecificationError(nullptr, nullptr, "funcname"); c.rethrowNoCurrentExceptionError(nullptr); } From e36986504dce47f04ede9c76850c2dc6c8955a78 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 14 Oct 2025 11:15:49 +0200 Subject: [PATCH 5/8] Format --- lib/checkexceptionsafety.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/checkexceptionsafety.cpp b/lib/checkexceptionsafety.cpp index fbdc55fc5b9..ed84b222dee 100644 --- a/lib/checkexceptionsafety.cpp +++ b/lib/checkexceptionsafety.cpp @@ -296,7 +296,7 @@ void CheckExceptionSafety::nothrowThrows() if (!function) continue; - bool isNoExcept = false, isEntryPoint = false; + bool isNoExcept = false, isEntryPoint = false; // check noexcept and noexcept(true) functions if (function->isNoExcept()) { @@ -323,7 +323,6 @@ void CheckExceptionSafety::nothrowThrows() else noexceptThrowError(throws); } - } } @@ -446,7 +445,7 @@ void CheckExceptionSafety::getErrorMessages(ErrorLogger *errorLogger, const Sett c.rethrowCopyError(nullptr, "varname"); c.catchExceptionByValueError(nullptr); c.noexceptThrowError(nullptr); - c.entryPointThrowError(nullptr); + c.entryPointThrowError(nullptr); c.unhandledExceptionSpecificationError(nullptr, nullptr, "funcname"); c.rethrowNoCurrentExceptionError(nullptr); } From 83217b896e74993a81ac4bd05ec4ae517f385e92 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 14 Oct 2025 11:16:32 +0200 Subject: [PATCH 6/8] Format --- lib/checkexceptionsafety.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/checkexceptionsafety.cpp b/lib/checkexceptionsafety.cpp index ed84b222dee..658a744c73a 100644 --- a/lib/checkexceptionsafety.cpp +++ b/lib/checkexceptionsafety.cpp @@ -296,7 +296,7 @@ void CheckExceptionSafety::nothrowThrows() if (!function) continue; - bool isNoExcept = false, isEntryPoint = false; + bool isNoExcept = false, isEntryPoint = false; // check noexcept and noexcept(true) functions if (function->isNoExcept()) { From 8fe787f23868a9eaafaace4f33e6ad336f754ddd Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 20 Oct 2025 21:50:39 +0200 Subject: [PATCH 7/8] Update checkexceptionsafety.cpp --- lib/checkexceptionsafety.cpp | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/lib/checkexceptionsafety.cpp b/lib/checkexceptionsafety.cpp index 658a744c73a..373dfde8254 100644 --- a/lib/checkexceptionsafety.cpp +++ b/lib/checkexceptionsafety.cpp @@ -297,19 +297,9 @@ void CheckExceptionSafety::nothrowThrows() continue; bool isNoExcept = false, isEntryPoint = false; - - // check noexcept and noexcept(true) functions - if (function->isNoExcept()) { - isNoExcept = true; - } - - // check throw() functions - else if (function->isThrow() && !function->throwArg) { - isNoExcept = true; - } - - // check __attribute__((nothrow)) or __declspec(nothrow) functions - else if (function->isAttributeNothrow()) { + if (function->isNoExcept() || // noexcept and noexcept(true) functions + (function->isThrow() && !function->throwArg) || // throw() functions + function->isAttributeNothrow()) { // __attribute__((nothrow)) or __declspec(nothrow) functions isNoExcept = true; } else if (mSettings->library.isentrypoint(function->name())) { @@ -317,6 +307,7 @@ void CheckExceptionSafety::nothrowThrows() } if (!isNoExcept && !isEntryPoint) continue; + if (const Token* throws = functionThrows(function)) { if (isEntryPoint) entryPointThrowError(throws); From 326932962dda23c2ad4fa8d8510e2a98aab28c55 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 20 Oct 2025 22:24:42 +0200 Subject: [PATCH 8/8] Update checkexceptionsafety.cpp --- lib/checkexceptionsafety.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/checkexceptionsafety.cpp b/lib/checkexceptionsafety.cpp index 373dfde8254..ca36d9627d2 100644 --- a/lib/checkexceptionsafety.cpp +++ b/lib/checkexceptionsafety.cpp @@ -307,7 +307,7 @@ void CheckExceptionSafety::nothrowThrows() } if (!isNoExcept && !isEntryPoint) continue; - + if (const Token* throws = functionThrows(function)) { if (isEntryPoint) entryPointThrowError(throws);