diff --git a/lib/exprengine.cpp b/lib/exprengine.cpp index 1966bb054..4e53434c0 100644 --- a/lib/exprengine.cpp +++ b/lib/exprengine.cpp @@ -476,6 +476,22 @@ static ExprEngine::ValuePtr executeAssign(const Token *tok, Data &data) auto val = std::dynamic_pointer_cast(pval); if (val) data.memory[val->varId] = rhsValue; + } else if (pval && pval->type() == ExprEngine::ValueType::BinOpResult) { + auto b = std::dynamic_pointer_cast(pval); + if (b && b->binop == "+") { + std::shared_ptr arr; + ExprEngine::ValuePtr offset; + if (b->op1->type() == ExprEngine::ValueType::ArrayValue) { + arr = std::dynamic_pointer_cast(b->op1); + offset = b->op2; + } else { + arr = std::dynamic_pointer_cast(b->op2); + offset = b->op1; + } + if (arr && offset) { + arr->assign(offset, rhsValue); + } + } } } return rhsValue; diff --git a/test/testexprengine.cpp b/test/testexprengine.cpp index ba50d710d..93ce43a39 100644 --- a/test/testexprengine.cpp +++ b/test/testexprengine.cpp @@ -57,9 +57,11 @@ private: TEST_CASE(pointerAlias1); TEST_CASE(pointerAlias2); + TEST_CASE(pointerAlias3); + TEST_CASE(pointerAlias4); } - std::string getRange(const char code[], const std::string &str) { + std::string getRange(const char code[], const std::string &str, int linenr = 0) { Settings settings; settings.platform(cppcheck::Platform::Unix64); settings.library.smartPointers.insert("std::shared_ptr"); @@ -68,7 +70,7 @@ private: tokenizer.tokenize(istr, "test.cpp"); std::string ret; std::function f = [&](const Token *tok, const ExprEngine::Value &value) { - if (tok->expressionString() == str) { + if ((linenr == 0 || linenr == tok->linenr()) && tok->expressionString() == str) { if (!ret.empty()) ret += ","; ret += value.getRange(); @@ -162,15 +164,28 @@ private: } void localArrayUninit() { - ASSERT_EQUALS("?", getRange("inf f() { int arr[10]; return arr[4]; }", "arr[4]")); + ASSERT_EQUALS("?", getRange("int f() { int arr[10]; return arr[4]; }", "arr[4]")); } void pointerAlias1() { - ASSERT_EQUALS("3", getRange("inf f() { int x; int *p = &x; x = 3; return *p; }", "return*p")); + ASSERT_EQUALS("3", getRange("int f() { int x; int *p = &x; x = 3; return *p; }", "return*p")); } void pointerAlias2() { - ASSERT_EQUALS("1", getRange("inf f() { int x; int *p = &x; *p = 1; return *p; }", "return*p")); + ASSERT_EQUALS("1", getRange("int f() { int x; int *p = &x; *p = 1; return *p; }", "return*p")); + } + + void pointerAlias3() { + ASSERT_EQUALS("7", getRange("int f() {\n" + " int x = 18;\n" + " int *p = &x;\n" + " *p = 7;\n" + " return x;\n" + "}", "x", 5)); + } + + void pointerAlias4() { + ASSERT_EQUALS("71", getRange("int f() { int x[10]; int *p = x+3; *p = 71; return x[3]; }", "x[3]")); } };