From b7d7633b97e3ebe487a230c33d852c81b8e2f377 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 30 Jun 2014 17:56:42 +0200 Subject: [PATCH] ValueFlow: Improved analysis after switch --- lib/valueflow.cpp | 7 +++++++ test/testvalueflow.cpp | 17 +++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 765bbf0ae..c4676af24 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -691,6 +691,13 @@ static bool valueFlowForward(Token * const startToken, } else if (indentlevel <= 0 && Token::Match(tok2, "break|continue|goto")) { + if (tok2->str() == "break") { + const Scope *scope = tok2->scope(); + if (scope && scope->type == Scope::eSwitch) { + tok2 = const_cast(scope->classEnd); + continue; + } + } if (settings->debugwarnings) bailout(tokenlist, errorLogger, tok2, "variable " + var->nameToken()->str() + ". noreturn conditional scope."); return false; diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 5ad789af1..238f4b7e8 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -468,8 +468,7 @@ private: " case 2: if (x==5) {} break;\n" " };\n" "}"); - ASSERT_EQUALS("[test.cpp:3]: (debug) ValueFlow bailout: variable x stopping on break\n" - "[test.cpp:4]: (debug) ValueFlow bailout: variable x. noreturn conditional scope.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:3]: (debug) ValueFlow bailout: variable x stopping on break\n", errout.str()); bailout("void f(int x, int y) {\n" " switch (y) {\n" @@ -477,8 +476,7 @@ private: " case 2: if (x==5) {} break;\n" " };\n" "}"); - ASSERT_EQUALS("[test.cpp:3]: (debug) ValueFlow bailout: variable x stopping on return\n" - "[test.cpp:4]: (debug) ValueFlow bailout: variable x. noreturn conditional scope.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:3]: (debug) ValueFlow bailout: variable x stopping on return\n", errout.str()); } void valueFlowBeforeConditionMacro() { @@ -745,6 +743,17 @@ private: " }\n" "}\n"; ASSERT_EQUALS(false, testValueOfX(code, 8U, 2)); // x is not 2 at line 8 + + code = "void f() {\n" + " int x;\n" + " switch (ab) {\n" + " case A: x = 12; break;\n" + " case B: x = 34; break;\n" + " }\n" + " v = x;\n" + "}"; + ASSERT_EQUALS(true, testValueOfX(code, 7U, 12)); + ASSERT_EQUALS(true, testValueOfX(code, 7U, 34)); } void valueFlowAfterCondition() {