ValueFlow: analysis in condition.
This commit is contained in:
parent
dec251ac44
commit
ef81bc363a
|
@ -815,6 +815,37 @@ static void valueFlowAfterCondition(TokenList *tokenlist, ErrorLogger *errorLogg
|
|||
std::list<ValueFlow::Value> values;
|
||||
values.push_back(ValueFlow::Value(tok, numtok ? MathLib::toLongNumber(numtok->str()) : 0LL));
|
||||
|
||||
if (Token::Match(tok->astParent(), "%oror%|&&")) {
|
||||
Token *parent = const_cast<Token*>(tok->astParent());
|
||||
const std::string &op(parent->str());
|
||||
|
||||
if (parent->astOperand1() == tok &&
|
||||
((op == "&&" && Token::Match(tok, "==|>=|<=|!")) ||
|
||||
(op == "||" && Token::Match(tok, "%var%|!=")))) {
|
||||
bool assign = false;
|
||||
for (; !assign && parent && parent->str() == op; parent = const_cast<Token*>(parent->astParent())) {
|
||||
std::stack<Token *> tokens;
|
||||
tokens.push(const_cast<Token*>(parent->astOperand2()));
|
||||
while (!tokens.empty()) {
|
||||
Token *rhstok = tokens.top();
|
||||
tokens.pop();
|
||||
if (!rhstok)
|
||||
continue;
|
||||
tokens.push(const_cast<Token*>(rhstok->astOperand1()));
|
||||
tokens.push(const_cast<Token*>(rhstok->astOperand2()));
|
||||
if (rhstok->varId() == varid)
|
||||
setTokenValue(rhstok, values.front());
|
||||
if (Token::Match(rhstok, "++|--|=") && Token::Match(rhstok->astOperand1(),"%varid%",varid)) {
|
||||
assign = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (parent->astParent() && parent == parent->astParent()->astOperand2())
|
||||
parent = const_cast<Token*>(parent->astParent());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const Token *top = tok->astTop();
|
||||
if (top && Token::Match(top->previous(), "if|while (") && !top->previous()->isExpandedMacro()) {
|
||||
// does condition reassign variable?
|
||||
|
|
|
@ -1059,7 +1059,7 @@ private:
|
|||
" p = q;\n"
|
||||
" if (p || *p) { }\n"
|
||||
"}");
|
||||
TODO_ASSERT_EQUALS("error", "", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:5]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n", errout.str());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -777,6 +777,19 @@ private:
|
|||
" a = x;\n"
|
||||
"}";
|
||||
ASSERT_EQUALS(true, testValueOfX(code, 3U, 3));
|
||||
|
||||
// In condition, after && and ||
|
||||
code = "void f(int x) {\n"
|
||||
" a = (x != 3 ||\n"
|
||||
" x);\n"
|
||||
"}";
|
||||
ASSERT_EQUALS(true, testValueOfX(code, 3U, 3));
|
||||
|
||||
code = "void f(int x) {\n"
|
||||
" a = (x == 4 &&\n"
|
||||
" x);\n"
|
||||
"}";
|
||||
ASSERT_EQUALS(true, testValueOfX(code, 3U, 4));
|
||||
}
|
||||
|
||||
void valueFlowBitAnd() {
|
||||
|
|
Loading…
Reference in New Issue