Refactoring: Use visitAstNodes

This commit is contained in:
Daniel Marjamäki 2018-11-23 19:16:19 +01:00
parent 5e727f92a0
commit 52f9650533
1 changed files with 31 additions and 46 deletions

View File

@ -483,23 +483,20 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
} }
} else { } else {
// is condition only depending on 1 variable? // is condition only depending on 1 variable?
std::stack<const Token*> tokens;
tokens.push(parent->astOperand1());
unsigned int varId = 0; unsigned int varId = 0;
while (!tokens.empty()) { bool ret = false;
const Token *t = tokens.top(); visitAstNodes(parent->astOperand1(),
tokens.pop(); [&](const Token *t) {
if (!t)
continue;
tokens.push(t->astOperand1());
tokens.push(t->astOperand2());
if (t->varId()) { if (t->varId()) {
if (varId > 0 || value.varId != 0U) if (varId > 0 || value.varId != 0U)
return; ret = true;
varId = t->varId(); varId = t->varId();
} else if (t->str() == "(" && Token::Match(t->previous(), "%name%")) } else if (t->str() == "(" && Token::Match(t->previous(), "%name%"))
return; // function call ret = true; // function call
} return ret ? ChildrenToVisit::done : ChildrenToVisit::op1_and_op2;
});
if (ret)
return;
ValueFlow::Value v(value); ValueFlow::Value v(value);
v.conditional = true; v.conditional = true;
@ -3167,23 +3164,17 @@ static void valueFlowAfterCondition(TokenList *tokenlist, SymbolDatabase* symbol
((op == "&&" && Token::Match(tok, "==|>=|<=|!")) || ((op == "&&" && Token::Match(tok, "==|>=|<=|!")) ||
(op == "||" && Token::Match(tok, "%name%|!=")))) { (op == "||" && Token::Match(tok, "%name%|!=")))) {
for (; parent && parent->str() == op; parent = const_cast<Token*>(parent->astParent())) { for (; parent && parent->str() == op; parent = const_cast<Token*>(parent->astParent())) {
std::stack<Token *> tokens;
tokens.push(const_cast<Token*>(parent->astOperand2()));
bool assign = false; bool assign = false;
while (!tokens.empty()) { visitAstNodes(parent->astOperand2(),
Token *rhstok = tokens.top(); [&](const Token *rhstok) {
tokens.pop();
if (!rhstok)
continue;
tokens.push(const_cast<Token*>(rhstok->astOperand1()));
tokens.push(const_cast<Token*>(rhstok->astOperand2()));
if (rhstok->varId() == varid) if (rhstok->varId() == varid)
setTokenValue(rhstok, true_values.front(), settings); setTokenValue(const_cast<Token *>(rhstok), true_values.front(), settings);
else if (Token::Match(rhstok, "++|--|=") && Token::Match(rhstok->astOperand1(), "%varid%", varid)) { else if (Token::Match(rhstok, "++|--|=") && Token::Match(rhstok->astOperand1(), "%varid%", varid)) {
assign = true; assign = true;
break; return ChildrenToVisit::done;
} }
} return ChildrenToVisit::op1_and_op2;
});
if (assign) if (assign)
break; break;
while (parent->astParent() && parent == parent->astParent()->astOperand2()) while (parent->astParent() && parent == parent->astParent()->astOperand2())
@ -3528,19 +3519,16 @@ static bool valueFlowForLoop2(const Token *tok,
return false; return false;
if (error) { if (error) {
// If a variable is reassigned in second expression, return false // If a variable is reassigned in second expression, return false
std::stack<const Token *> tokens; bool reassign = false;
tokens.push(secondExpression); visitAstNodes(secondExpression,
while (!tokens.empty()) { [&](const Token *t) {
const Token *t = tokens.top();
tokens.pop();
if (!t)
continue;
if (t->str() == "=" && t->astOperand1() && programMemory.hasValue(t->astOperand1()->varId())) if (t->str() == "=" && t->astOperand1() && programMemory.hasValue(t->astOperand1()->varId()))
// TODO: investigate what variable is assigned. // TODO: investigate what variable is assigned.
return false; reassign = true;
tokens.push(t->astOperand1()); return reassign ? ChildrenToVisit::done : ChildrenToVisit::op1_and_op2;
tokens.push(t->astOperand2()); });
} if (reassign)
return false;
} }
ProgramMemory startMemory(programMemory); ProgramMemory startMemory(programMemory);
@ -4213,18 +4201,15 @@ static bool hasContainerSizeGuard(const Token *tok, unsigned int containerId)
if (!Token::Match(parent, "%oror%|&&|?")) if (!Token::Match(parent, "%oror%|&&|?"))
continue; continue;
// is container found in lhs? // is container found in lhs?
std::stack<const Token *> tokens; bool found = false;
tokens.push(parent->astOperand1()); visitAstNodes(parent->astOperand1(),
while (!tokens.empty()) { [&](const Token *t) {
const Token *t = tokens.top();
tokens.pop();
if (!t)
continue;
if (t->varId() == containerId) if (t->varId() == containerId)
return true; found = true;
tokens.push(t->astOperand1()); return found ? ChildrenToVisit::done : ChildrenToVisit::op1_and_op2;
tokens.push(t->astOperand2()); });
} if (found)
return true;
} }
return false; return false;
} }