value flow: improved calculations that depends on variable
This commit is contained in:
parent
79a1244a54
commit
bb3cc67aaa
|
@ -170,11 +170,13 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value)
|
|||
std::list<ValueFlow::Value>::const_iterator value1, value2;
|
||||
for (value1 = parent->astOperand1()->values.begin(); value1 != parent->astOperand1()->values.end(); ++value1) {
|
||||
for (value2 = parent->astOperand2()->values.begin(); value2 != parent->astOperand2()->values.end(); ++value2) {
|
||||
if (value1->varId == 0U || value2->varId == 0U || value1->varId == value2->varId) {
|
||||
if (value1->varId == 0U || value2->varId == 0U ||
|
||||
(value1->varId == value2->varId && value1->varvalue == value2->varvalue)) {
|
||||
ValueFlow::Value result(0);
|
||||
result.condition = value1->condition ? value1->condition : value2->condition;
|
||||
result.inconclusive = value1->inconclusive | value2->inconclusive;
|
||||
result.varId = (value1->varId != 0U) ? value1->varId : value2->varId;
|
||||
result.varvalue = (result.varId == value1->varId) ? value1->intvalue : value2->intvalue;
|
||||
switch (parent->str()[0]) {
|
||||
case '+':
|
||||
result.intvalue = value1->intvalue + value2->intvalue;
|
||||
|
|
|
@ -29,9 +29,9 @@ class Settings;
|
|||
namespace ValueFlow {
|
||||
class Value {
|
||||
public:
|
||||
Value() : condition(0), intvalue(0), inconclusive(false), varId(0U) {}
|
||||
Value(long long val) : condition(0), intvalue(val), inconclusive(false), varId(0U) {}
|
||||
Value(const Token *c, long long val) : condition(c), intvalue(val), inconclusive(false), varId(0U) {}
|
||||
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) {}
|
||||
|
||||
/** Condition that this value depends on (TODO: replace with a 'callstack') */
|
||||
const Token *condition;
|
||||
|
@ -44,6 +44,9 @@ namespace ValueFlow {
|
|||
|
||||
/** For calculated values - varId that calculated value depends on */
|
||||
unsigned int varId;
|
||||
|
||||
/** For calculated values - variable value that calculated value depends on */
|
||||
long long varvalue;
|
||||
};
|
||||
|
||||
void setValues(TokenList *tokenlist, ErrorLogger *errorLogger, const Settings *settings);
|
||||
|
|
|
@ -95,14 +95,19 @@ private:
|
|||
tokenizer.tokenize(istr, "test.cpp");
|
||||
}
|
||||
|
||||
ValueFlow::Value valueOfTok(const char code[], const char tokstr[]) {
|
||||
std::list<ValueFlow::Value> tokenValues(const char code[], const char tokstr[]) {
|
||||
const Settings settings;
|
||||
Tokenizer tokenizer(&settings, this);
|
||||
std::istringstream istr(code);
|
||||
errout.str("");
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
const Token *tok = Token::findmatch(tokenizer.tokens(), tokstr);
|
||||
return (tok && tok->values.size()==1U) ? tok->values.front() : ValueFlow::Value();
|
||||
return tok ? tok->values : std::list<ValueFlow::Value>();
|
||||
}
|
||||
|
||||
ValueFlow::Value valueOfTok(const char code[], const char tokstr[]) {
|
||||
std::list<ValueFlow::Value> values = tokenValues(code, tokstr);
|
||||
return values.size() == 1U ? values.front() : ValueFlow::Value();
|
||||
}
|
||||
|
||||
void valueFlowNumber() {
|
||||
|
@ -128,6 +133,12 @@ private:
|
|||
"}";
|
||||
ASSERT_EQUALS(579, valueOfTok(code, "+").intvalue);
|
||||
|
||||
code = "void f(int x, int y) {\n"
|
||||
" a = x+y;\n"
|
||||
" if (x==123 || y==456) {}"
|
||||
"}";
|
||||
ASSERT_EQUALS(0, valueOfTok(code, "+").intvalue);
|
||||
|
||||
code = "void f(int x) {\n"
|
||||
" a = x+x;\n"
|
||||
" if (x==123) {}"
|
||||
|
@ -135,10 +146,14 @@ private:
|
|||
ASSERT_EQUALS(246, valueOfTok(code, "+").intvalue);
|
||||
|
||||
code = "void f(int x, int y) {\n"
|
||||
" a = x+y;\n"
|
||||
" if (x==123 || y==456) {}"
|
||||
" a = x*x;\n"
|
||||
" if (x==2) {}\n"
|
||||
" if (x==4) {}\n"
|
||||
"}";
|
||||
ASSERT_EQUALS(0, valueOfTok(code, "+").intvalue);
|
||||
std::list<ValueFlow::Value> values = tokenValues(code,"*");
|
||||
ASSERT_EQUALS(2U, values.size());
|
||||
ASSERT_EQUALS(4, values.front().intvalue);
|
||||
ASSERT_EQUALS(16, values.back().intvalue);
|
||||
}
|
||||
|
||||
void valueFlowBeforeCondition() {
|
||||
|
|
Loading…
Reference in New Issue