Fixed #6826 (False positive: ValueFlow conditional value used in condition)

This commit is contained in:
Daniel Marjamäki 2015-07-12 19:35:47 +02:00
parent a4a866ab07
commit 7ccd30362c
2 changed files with 21 additions and 2 deletions

View File

@ -354,6 +354,7 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value)
} }
ValueFlow::Value v(value); ValueFlow::Value v(value);
v.conditional = true;
if (!variables.empty()) if (!variables.empty())
v.varId = *(variables.begin()); v.varId = *(variables.begin());
@ -897,6 +898,7 @@ static bool valueFlowForward(Token * const startToken,
if (tok3->varId() == varid) { if (tok3->varId() == varid) {
for (std::list<ValueFlow::Value>::const_iterator it = values.begin(); it != values.end(); ++it) for (std::list<ValueFlow::Value>::const_iterator it = values.begin(); it != values.end(); ++it)
setTokenValue(tok3, *it); setTokenValue(tok3, *it);
} else if (Token::Match(tok3, "%oror%|&&|?")) {
break; break;
} }
} }
@ -1143,10 +1145,21 @@ static bool valueFlowForward(Token * const startToken,
} }
{ {
// Is variable usage protected by && || ?:
const Token *tok3 = tok2;
const Token *parent = tok3->astParent();
while (parent && !Token::Match(parent, "%oror%|&&|:")) {
tok3 = parent;
parent = parent->astParent();
}
const bool conditional = parent && (parent->str() == ":" || parent->astOperand2() == tok3);
std::list<ValueFlow::Value>::const_iterator it; std::list<ValueFlow::Value>::const_iterator it;
for (it = values.begin(); it != values.end(); ++it) for (it = values.begin(); it != values.end(); ++it) {
if (!conditional || !it->conditional)
setTokenValue(tok2, *it); setTokenValue(tok2, *it);
} }
}
// increment/decrement // increment/decrement
if (Token::Match(tok2->previous(), "++|-- %name%") || Token::Match(tok2, "%name% ++|--")) { if (Token::Match(tok2->previous(), "++|-- %name%") || Token::Match(tok2, "%name% ++|--")) {

View File

@ -913,6 +913,12 @@ private:
"}"; "}";
ASSERT_EQUALS(false, testValueOfX(code, 8U, 0)); ASSERT_EQUALS(false, testValueOfX(code, 8U, 0));
code = "void f(int a) {\n" // #6826
" int x = a ? a : 87;\n"
" if (a && x) {}\n"
"}";
ASSERT_EQUALS(false, testValueOfX(code, 3U, 87));
// pointer/reference to x // pointer/reference to x
code = "int f(void) {\n" code = "int f(void) {\n"
" int x = 2;\n" " int x = 2;\n"