From 11e32ff445ccc5b13f0321217d31771ce75cf70d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Tue, 12 Mar 2019 18:53:58 +0100 Subject: [PATCH 1/2] ValueFlow: Handle compound assignments in execute() --- lib/valueflow.cpp | 35 +++++++++++++++++++++++++++++++---- test/testvalueflow.cpp | 7 +++++++ 2 files changed, 38 insertions(+), 4 deletions(-) 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" From 2a006676090d37cd2c65630d47aabe0ad449f46e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Tue, 12 Mar 2019 18:58:14 +0100 Subject: [PATCH 2/2] CheckBufferOverrun: cleanup --- lib/checkbufferoverrun.h | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/lib/checkbufferoverrun.h b/lib/checkbufferoverrun.h index e897180eb..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 /// @{ @@ -73,14 +59,14 @@ public: : Check(myName(), tokenizer, settings, errorLogger) { } - void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) OVERRIDE { + void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) OVERRIDE { CheckBufferOverrun checkBufferOverrun(tokenizer, settings, errorLogger); checkBufferOverrun.arrayIndex(); checkBufferOverrun.bufferOverflow(); checkBufferOverrun.arrayIndexThenCheck(); } - void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) OVERRIDE { + void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) OVERRIDE { (void)tokenizer; (void)settings; (void)errorLogger;