diff --git a/lib/checkfunctions.cpp b/lib/checkfunctions.cpp index 8884a03fc48..1ab21eacfd2 100644 --- a/lib/checkfunctions.cpp +++ b/lib/checkfunctions.cpp @@ -396,6 +396,19 @@ static const Token *checkMissingReturnScope(const Token *tok, const Library &lib if (Token::simpleMatch(tok->tokAt(-2), "} else {")) return checkMissingReturnScope(tok->tokAt(-2), library); return tok; + } else if (tok->scope()->type == ScopeType::eCatch) { + while (tok->str() == "}") { + const Token *errorToken = checkMissingReturnScope(tok, library); + if (errorToken || tok->scope()->type == ScopeType::eTry) + return errorToken; + tok = tok->link(); + if (Token::simpleMatch(tok->previous(), ") {") && Token::simpleMatch(tok->linkAt(-1)->tokAt(-2), "} catch (")) + tok = tok->linkAt(-1)->tokAt(-2); + else + break; + } + // FIXME this should not be reached + return nullptr; } // FIXME return nullptr; diff --git a/test/testfunctions.cpp b/test/testfunctions.cpp index da589c765fe..6aa4e6534a2 100644 --- a/test/testfunctions.cpp +++ b/test/testfunctions.cpp @@ -85,6 +85,7 @@ class TestFunctions : public TestFixture { TEST_CASE(checkMissingReturn4); TEST_CASE(checkMissingReturn5); TEST_CASE(checkMissingReturn6); // #13180 + TEST_CASE(checkMissingReturn7); // #14370 - FN try/catch // std::move for locar variable TEST_CASE(returnLocalStdMove1); @@ -1880,6 +1881,43 @@ class TestFunctions : public TestFixture { ASSERT_EQUALS("[test.cpp:3:5]: (error) Found an exit path from function with non-void return type that has missing return statement [missingReturn]\n", errout_str()); } + void checkMissingReturn7() {// #14370 FN try/catch + check("int foo(void) {\n" + " try { return readData(); }\n" + " catch (...) {}\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3:18]: (error) Found an exit path from function with non-void return type that has missing return statement [missingReturn]\n", errout_str()); + + check("int foo(void) {\n" + " try { return readData(); }\n" + " catch (const E& e) {}\n" + " catch (...) { return 2; }\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3:25]: (error) Found an exit path from function with non-void return type that has missing return statement [missingReturn]\n", errout_str()); + + check("int foo(void) {\n" + " try { x=1; }\n" + " catch (...) { return 2; }\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2:11]: (error) Found an exit path from function with non-void return type that has missing return statement [missingReturn]\n", errout_str()); + + check("int foo(void) {\n" + " try { return readData(); }\n" + " catch (...) { return 0; }\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + check("int foo(void)\n" + " try { x=1; }\n" + " catch (...) { return 2; }\n"); + ASSERT_EQUALS("[test.cpp:2:11]: (error) Found an exit path from function with non-void return type that has missing return statement [missingReturn]\n", errout_str()); + + check("int foo(void)\n" + " try { return readData(); }\n" + " catch (...) { }\n"); + ASSERT_EQUALS("[test.cpp:3:19]: (error) Found an exit path from function with non-void return type that has missing return statement [missingReturn]\n", errout_str()); + } + // NRVO check void returnLocalStdMove1() { check("struct A{}; A f() { A var; return std::move(var); }");