diff --git a/lib/checkbufferoverrun.h b/lib/checkbufferoverrun.h index 635da63cc..0e4997506 100644 --- a/lib/checkbufferoverrun.h +++ b/lib/checkbufferoverrun.h @@ -34,20 +34,6 @@ #include #include -class Settings; -class SymbolDatabase; -class Token; -namespace ValueFlow { - class Value; -} // namespace ValueFlow -namespace tinyxml2 { - class XMLElement; -} // namespace tinyxml2 - -// CWE ids used -static const struct CWE CWE119(119U); // Improper Restriction of Operations within the Bounds of a Memory Buffer - -class Variable; /// @addtogroup Checks /// @{ diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index fb3a60559..453d6dcf0 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -3766,12 +3766,39 @@ static void execute(const Token *expr, *result = result1 != result2; } - else if (expr->str() == "=") { + else if (expr->isAssignmentOp()) { execute(expr->astOperand2(), programMemory, result, error); - if (!*error && expr->astOperand1() && expr->astOperand1()->varId()) - programMemory->setIntValue(expr->astOperand1()->varId(), *result); - else + if (!expr->astOperand1() || !expr->astOperand1()->varId()) *error = true; + if (*error) + return; + + if (expr->str() == "=") { + programMemory->setIntValue(expr->astOperand1()->varId(), *result); + return; + } + + long long intValue; + if (!programMemory->getIntValue(expr->astOperand1()->varId(), &intValue)) { + *error = true; + return; + } + if (expr->str() == "+=") + programMemory->setIntValue(expr->astOperand1()->varId(), intValue + *result); + else if (expr->str() == "-=") + programMemory->setIntValue(expr->astOperand1()->varId(), intValue - *result); + else if (expr->str() == "*=") + programMemory->setIntValue(expr->astOperand1()->varId(), intValue * *result); + else if (expr->str() == "/=" && *result != 0) + programMemory->setIntValue(expr->astOperand1()->varId(), intValue / *result); + else if (expr->str() == "%=" && *result != 0) + programMemory->setIntValue(expr->astOperand1()->varId(), intValue % *result); + else if (expr->str() == "&=") + programMemory->setIntValue(expr->astOperand1()->varId(), intValue & *result); + else if (expr->str() == "|=") + programMemory->setIntValue(expr->astOperand1()->varId(), intValue | *result); + else if (expr->str() == "^=") + programMemory->setIntValue(expr->astOperand1()->varId(), intValue ^ *result); } else if (Token::Match(expr, "++|--")) { diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 22b0a4690..73caed889 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -2558,6 +2558,13 @@ private: "}"; ASSERT_EQUALS(true, testValueOfX(code, 3U, 9)); + code = "void f() {\n" + " for (int x = 0; x < 5; x += 2)\n" + " a[x] = 0;\n" + "}"; + ASSERT_EQUALS(true, testValueOfX(code, 3U, 0)); + ASSERT_EQUALS(true, testValueOfX(code, 3U, 4)); + code = "void f() {\n" " for (int x = 0; x < 10; x = x + 2)\n" " a[x] = 0;\n"