From e75971019866e382425e40152026447bda2427c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Tue, 28 Jul 2015 08:58:05 +0200 Subject: [PATCH] Fixed #6743 (valueFlowAfterCondition: wrong value when variable is changed in conditional code) --- lib/valueflow.cpp | 15 +++++++++++---- test/testvalueflow.cpp | 14 ++++++++++++-- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 2ab272dc3..9827380b8 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -1558,12 +1558,19 @@ static void valueFlowAfterCondition(TokenList *tokenlist, SymbolDatabase* symbol startToken = top->link()->linkAt(1)->tokAt(2); } - bool ok = true; - if (startToken) - ok = valueFlowForward(startToken->next(), startToken->link(), var, varid, values, true, tokenlist, errorLogger, settings); + if (startToken) { + if (!valueFlowForward(startToken->next(), startToken->link(), var, varid, values, true, tokenlist, errorLogger, settings)) + continue; + if (isVariableChanged(startToken, startToken->link(), varid)) { + // TODO: The endToken should not be startToken->link() in the valueFlowForward call + if (settings->debugwarnings) + bailout(tokenlist, errorLogger, startToken->link(), "valueFlowAfterCondition: " + var->name() + " is changed in conditional block"); + continue; + } + } // After conditional code.. - if (ok && Token::simpleMatch(top->link(), ") {")) { + if (Token::simpleMatch(top->link(), ") {")) { Token *after = top->link()->linkAt(1); std::string unknownFunction; if (settings->library.isScopeNoReturn(after, &unknownFunction)) { diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index ea98b2b4c..111f084ce 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -1067,7 +1067,7 @@ private: void valueFlowAfterCondition() { const char *code; - // if + // in if code = "void f(int x) {\n" " if (x == 123) {\n" " a = x;\n" @@ -1082,7 +1082,7 @@ private: "}"; ASSERT_EQUALS(false, testValueOfX(code, 3U, 123)); - // else + // in else code = "void f(int x) {\n" " if (x == 123) {}\n" " else a = x;\n" @@ -1095,6 +1095,16 @@ private: "}"; ASSERT_EQUALS(true, testValueOfX(code, 3U, 123)); + // after if + code = "void f(int x) {\n" + " if (x == 10) {\n" + " x++;\n" + " }\n" + " a = x;\n" + "}"; + ASSERT_EQUALS(false, testValueOfX(code, 5U, 10)); + TODO_ASSERT_EQUALS(true, false, testValueOfX(code, 5U, 11)); + // ! code = "void f(int x) {\n" " if (!x) { a = x; }\n"