diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 99490707cb3..7a6682973ff 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -871,8 +871,21 @@ static bool isVardeclInSwitch(const Token* tok) return false; if (!isNestedInSwitch(tok->scope())) return false; - const Token* end = Token::findsimplematch(tok, ";"); - return end && end->previous()->variable() && end->previous()->variable()->nameToken() == end->previous(); + if (const Token* end = Token::findsimplematch(tok, ";")) { + for (const Token* tok2 = tok; tok2 != end; tok2 = tok2->next()) { + if (tok2->isKeyword() && tok2->str() == "case") + return false; + if (tok2->variable() && tok2->variable()->nameToken() == tok2) { + end = tok2->scope()->bodyEnd; + for (const Token* tok3 = tok2; tok3 != end; tok3 = tok3->next()) { + if (tok3->isKeyword()) + return tok3->str() == "case"; + } + return false; + } + } + } + return false; } //--------------------------------------------------------------------------- diff --git a/test/testother.cpp b/test/testother.cpp index 4dceade465e..25998f61300 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -5710,6 +5710,20 @@ class TestOther : public TestFixture { "}\n"); ASSERT_EQUALS("", errout_str()); + check("int f(int i) {\n" + " switch (i) {\n" + " case 0:\n" + " return 0;\n" + " int a[1];\n" + " case 1:\n" + " case 2:\n" + " a[0] = 5;\n" + " return a[0] + i;\n" + " }\n" + " return 3;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + check("int f(int i) {\n" " switch (i) {\n" " case 0:\n" @@ -5780,6 +5794,18 @@ class TestOther : public TestFixture { " return x;\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("bool f(int x, int y) {\n" // #13544 + " switch (x) {\n" + " case 1: {\n" + " return y != 0;\n" + " int z = y + 5;\n" + " return z != 7;\n" + " }\n" + " }\n" + " return false;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:5]: (style) Statements following 'return' will never be executed.\n", errout_str()); }