ExprEngine: Better handling of compound assignments

This commit is contained in:
Daniel Marjamäki 2019-09-21 21:15:51 +02:00
parent 52aab1e80c
commit 7d6fd915be
2 changed files with 19 additions and 3 deletions

View File

@ -422,7 +422,17 @@ static ExprEngine::ValuePtr executeReturn(const Token *tok, Data &data)
static ExprEngine::ValuePtr executeAssign(const Token *tok, Data &data)
{
ExprEngine::ValuePtr rhsValue = executeExpression(tok->astOperand2(), data);
call(data.callbacks, tok, rhsValue);
if (tok->str() == "=")
call(data.callbacks, tok, rhsValue);
else {
// "+=" => "+"
std::string binop(tok->str());
binop = binop.substr(0, binop.size() - 1);
ExprEngine::ValuePtr lhsValue = executeExpression(tok->astOperand1(), data);
auto newValue = std::make_shared<ExprEngine::BinOpResult>(binop, lhsValue, rhsValue);
call(data.callbacks, tok, newValue);
rhsValue = newValue;
}
const Token *lhsToken = tok->astOperand1();
data.trackAssignment(lhsToken, rhsValue);
@ -561,7 +571,8 @@ static ExprEngine::ValuePtr executeExpression(const Token *tok, Data &data)
if (tok->str() == "return")
return executeReturn(tok, data);
if (tok->str() == "=")
if (tok->isAssignmentOp())
// TODO: Handle more operators
return executeAssign(tok, data);
if (tok->astOperand1() && tok->astOperand2() && tok->str() == "[")
@ -597,7 +608,7 @@ static ExprEngine::ValuePtr executeExpression(const Token *tok, Data &data)
static void execute(const Token *start, const Token *end, Data &data)
{
for (const Token *tok = start; tok != end; tok = tok->next()) {
if (tok->str() == ";")
if (Token::Match(tok, "[;{}]"))
data.trackProgramState(tok);
if (tok->variable() && tok->variable()->nameToken() == tok) {
if (tok->variable()->isArray() && tok->variable()->dimensions().size() == 1 && tok->variable()->dimensions()[0].known) {

View File

@ -37,6 +37,7 @@ private:
TEST_CASE(expr3);
TEST_CASE(expr4);
TEST_CASE(expr5);
TEST_CASE(exprAssign1);
TEST_CASE(functionCall1);
@ -110,6 +111,10 @@ private:
ASSERT_EQUALS("-65536:65534", getRange("void f(short a, short b, short c, short d) { if (a+b<c+d) {} }", "a+b"));
}
void exprAssign1() {
ASSERT_EQUALS("1:256", getRange("void f(unsigned char a) { a += 1; }", "a+=1"));
}
void functionCall1() {
ASSERT_EQUALS("-2147483648:2147483647", getRange("int atoi(const char *p); void f() { int x = atoi(a); x = x; }", "x=x"));
}