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

View File

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

View File

@ -560,6 +560,15 @@ private:
" if (a!=132) {}\n" " if (a!=132) {}\n"
"}"; "}";
ASSERT_EQUALS(true, testValueOfX(code, 3U, 132)); 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() { void valueFlowForLoop() {