diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 1c081d0c8..7bada82d6 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -184,7 +184,7 @@ static void valueFlowBeforeCondition(TokenList *tokenlist, ErrorLogger *errorLog continue; // extra logic for unsigned variables 'i>=1' => possible value can also be 0 - const ValueFlow::Value val(tok, num); + ValueFlow::Value val(tok, num); ValueFlow::Value val2; if (num==1U && Token::Match(tok,"<=|>=")) { bool isunsigned = false; @@ -214,6 +214,17 @@ static void valueFlowBeforeCondition(TokenList *tokenlist, ErrorLogger *errorLog break; } + // increment/decrement + if (Token::Match(tok2->previous(), "[;{}] %var% ++|-- ;")) + val.intvalue += (tok2->strAt(1)=="++") ? -1 : 1; + else if (Token::Match(tok2->tokAt(-2), "[;{}] ++|-- %var% ;")) + val.intvalue += (tok2->strAt(-1)=="++") ? -1 : 1; + else if (Token::Match(tok2->previous(), "++|-- %var%") || Token::Match(tok2, "%var% ++|--")) { + if (settings->debugwarnings) + bailout(tokenlist, errorLogger, tok2, "increment/decrement of " + tok2->str()); + break; + } + // bailout: variable is used in rhs in assignment to itself if (bailoutSelfAssignment(tok2)) { if (settings->debugwarnings) diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 7a56c5c1f..141183962 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -109,7 +109,7 @@ private: "}"; ASSERT_EQUALS(true, testValueOfX(code, 3U, 123)); - // assignment + // assignment / increment code = "void f(int x) {\n" " x = 2 + x;\n" " if (x == 65);\n" @@ -122,6 +122,19 @@ private: "}"; ASSERT_EQUALS(false, testValueOfX(code, 2U, 65)); + code = "void f(int x) {\n" + " a[x++] = 0;\n" + " if (x == 5);\n" + "}"; + ASSERT_EQUALS(false, testValueOfX(code, 2U, 5)); + + code = "void f(int x) {\n" + " a = x;\n" + " x++;\n" + " if (x == 4);\n" + "}"; + ASSERT_EQUALS(true, testValueOfX(code, 2U, 3)); + // guarding by && code = "void f(int x) {\n" " if (!x || \n" // <- x can be 0