value flow: fix fp when conditional value is assigned

This commit is contained in:
Daniel Marjamäki 2014-01-25 20:14:49 +01:00
parent c1e35e1df1
commit c5971b7137
3 changed files with 24 additions and 7 deletions

View File

@ -498,11 +498,10 @@ static void valueFlowAfterAssign(TokenList *tokenlist, ErrorLogger *errorLogger,
// Remove conditional values
std::list<ValueFlow::Value>::iterator it;
for (it = values.begin(); it != values.end();) {
if (it->condition) {
if (it->condition || it->conditional)
values.erase(it++);
} else {
else
++it;
}
}
}
if (Token::findmatch(start, "++|-- %varid%", end, varid) ||
@ -522,9 +521,15 @@ static void valueFlowAfterAssign(TokenList *tokenlist, ErrorLogger *errorLogger,
}
}
else if (tok2->str() == "}")
else if (tok2->str() == "}") {
++number_of_if;
// Set "conditional" flag for all values
std::list<ValueFlow::Value>::iterator it;
for (it = values.begin(); it != values.end(); ++it)
it->conditional = true;
}
if (tok2->varId() == varid) {
// bailout: assignment
if (Token::Match(tok2->previous(), "!!* %var% =")) {

View File

@ -29,13 +29,16 @@ class Settings;
namespace ValueFlow {
class Value {
public:
Value() : condition(0), intvalue(0), inconclusive(false), varId(0U), varvalue(0) {}
Value(long long val) : condition(0), intvalue(val), inconclusive(false), varId(0U), varvalue(val) {}
Value(const Token *c, long long val) : condition(c), intvalue(val), inconclusive(false), varId(0U), varvalue(val) {}
Value() : condition(0), conditional(false), intvalue(0), inconclusive(false), varId(0U), varvalue(0) {}
Value(long long val) : condition(0), conditional(false), intvalue(val), inconclusive(false), varId(0U), varvalue(val) {}
Value(const Token *c, long long val) : condition(c), conditional(false), intvalue(val), inconclusive(false), varId(0U), varvalue(val) {}
/** Condition that this value depends on (TODO: replace with a 'callstack') */
const Token *condition;
/** Conditional value */
bool conditional;
/** int value */
long long intvalue;

View File

@ -560,6 +560,15 @@ private:
" if (a!=132) {}\n"
"}";
ASSERT_EQUALS(true, testValueOfX(code, 3U, 132));
code = "void f() {\n"
" int a;\n"
" if (n) { a = n; }\n"
" else { a = 0; }\n"
" int x = a;\n"
" if (a > 0) { a = b / x; }\n"
"}";
ASSERT_EQUALS(false, testValueOfX(code, 6U, 0));
}
void valueFlowForLoop() {