From 3e6540c4b392d47bd6f70c0ee0312564a65851a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 31 Oct 2021 14:47:52 +0100 Subject: [PATCH] Fixed #10523 (FP: missingReturn with nested switch statements) --- lib/checkfunctions.cpp | 12 ++++++++---- test/testfunctions.cpp | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/lib/checkfunctions.cpp b/lib/checkfunctions.cpp index 802fd94ba..87f200bdb 100644 --- a/lib/checkfunctions.cpp +++ b/lib/checkfunctions.cpp @@ -303,9 +303,13 @@ static const Token *checkMissingReturnScope(const Token *tok, const Library &lib // find reachable break / !default bool hasDefault = false; bool reachable = false; - for (const Token *switchToken = tok->link(); switchToken != tok; switchToken = switchToken->next()) { - if (reachable && Token::simpleMatch(switchToken, "break ;")) - return switchToken; + for (const Token *switchToken = tok->link()->next(); switchToken != tok; switchToken = switchToken->next()) { + if (reachable && Token::simpleMatch(switchToken, "break ;")) { + if (Token::simpleMatch(switchToken->previous(), "}") && !checkMissingReturnScope(switchToken->previous(), library)) + reachable = false; + else + return switchToken; + } if (switchToken->isKeyword() && Token::Match(switchToken, "return|throw")) reachable = false; if (Token::Match(switchToken, "%name% (") && library.isnoreturn(switchToken)) @@ -314,7 +318,7 @@ static const Token *checkMissingReturnScope(const Token *tok, const Library &lib reachable = true; if (Token::simpleMatch(switchToken, "default :")) hasDefault = true; - else if (switchToken->str() == "{" && switchToken->scope()->isLoopScope()) + else if (switchToken->str() == "{" && (switchToken->scope()->isLoopScope() || switchToken->scope()->type == Scope::ScopeType::eSwitch)) switchToken = switchToken->link(); } if (!hasDefault) diff --git a/test/testfunctions.cpp b/test/testfunctions.cpp index eae150925..9eca6b483 100644 --- a/test/testfunctions.cpp +++ b/test/testfunctions.cpp @@ -1441,6 +1441,20 @@ private: "}"); ASSERT_EQUALS("", errout.str()); + check("bool test(unsigned char v1, int v2) {\n" + " switch (v1) {\n" + " case 0:\n" + " switch (v2) {\n" + " case 48000:\n" + " break;\n" + " }\n" + " return false;\n" + " default:\n" + " return true;\n" + " }\n" + "}"); + ASSERT_EQUALS("", errout.str()); + // if/else check("int f(int x) {\n" " if (x) {\n"