From ca1f19b6d439ad6e35ac3b935135119e393dd8df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 2 May 2015 17:30:09 +0200 Subject: [PATCH] Fixed #6378 (valueFlowForward: decrement not handled) --- lib/valueflow.cpp | 35 ++++++++++++++++++++++++++++------- test/testsimplifytypedef.cpp | 2 +- test/testvalueflow.cpp | 3 ++- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 800164851..2299114dd 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -1043,13 +1043,6 @@ static bool valueFlowForward(Token * const startToken, return false; } - // bailout increment/decrement for now.. - if (Token::Match(tok2->previous(), "++|-- %name%") || Token::Match(tok2, "%name% ++|--")) { - if (settings->debugwarnings) - bailout(tokenlist, errorLogger, tok2, "increment/decrement of " + tok2->str()); - return false; - } - // bailout: possible assignment using >> if (Token::Match(tok2->previous(), ">> %name% >>|;")) { const Token *parent = tok2->previous(); @@ -1081,6 +1074,34 @@ static bool valueFlowForward(Token * const startToken, setTokenValue(tok2, *it); } + // increment/decrement + if (Token::Match(tok2->previous(), "++|-- %name%") || Token::Match(tok2, "%name% ++|--")) { + const bool pre = Token::Match(tok2->previous(), "++|--"); + Token * const op = pre ? tok2->previous() : tok2->next(); + const bool inc = (op->str() == "++"); + std::list::iterator it; + // Erase values that are not int values.. + for (it = values.begin(); it != values.end();) { + if (it->tokvalue) + it = values.erase(it); + else + ++it; + } + if (values.empty()) { + if (settings->debugwarnings) + bailout(tokenlist, errorLogger, tok2, "increment/decrement of " + tok2->str()); + return false; + } + // Perform increment/decrement.. + for (it = values.begin(); it != values.end(); ++it) { + if (!pre) + setTokenValue(op, *it); + it->intvalue += (inc ? 1 : -1); + if (pre) + setTokenValue(op, *it); + } + } + // bailout if address of var is taken.. if (tok2->astParent() && tok2->astParent()->str() == "&" && !tok2->astParent()->astOperand2()) { if (settings->debugwarnings) diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index b312ab8a7..36272027c 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -1099,7 +1099,7 @@ private: "[test.cpp:20] -> [test.cpp:1]: (style, inconclusive) The function parameter 'A' hides a typedef with the same name.\n" "[test.cpp:21] -> [test.cpp:1]: (style, inconclusive) The variable 'A' hides a typedef with the same name.\n" "[test.cpp:24] -> [test.cpp:1]: (style, inconclusive) The typedef 'A' hides a typedef with the same name.\n" - "[test.cpp:21]: (debug) ValueFlow bailout: increment/decrement of a\n", errout.str()); + , errout.str()); } void simplifyTypedef36() { diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index fa482de78..c9ec34653 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -641,6 +641,7 @@ private: " return x;\n" "}"; ASSERT_EQUALS(false, testValueOfX(code, 4U, 9)); + ASSERT_EQUALS(true, testValueOfX(code, 4U, 8)); code = "void f() {\n" " int x = 0;\n" @@ -1346,7 +1347,7 @@ private: " for (x = 0; x < 20; x++) {}\n" " a = x++;\n" "}\n"; - TODO_ASSERT_EQUALS(true, false, testValueOfX(code, 4U, 20)); + ASSERT_EQUALS(true, testValueOfX(code, 4U, 20)); code = "void f() {\n" " int x;\n"