ValueFlow: Added float type
This commit is contained in:
parent
4732667488
commit
e1e9eacccc
|
@ -1325,10 +1325,17 @@ void Token::printValueFlow(bool xml, std::ostream &out) const
|
||||||
for (std::list<ValueFlow::Value>::const_iterator it=tok->values.begin(); it!=tok->values.end(); ++it) {
|
for (std::list<ValueFlow::Value>::const_iterator it=tok->values.begin(); it!=tok->values.end(); ++it) {
|
||||||
if (xml) {
|
if (xml) {
|
||||||
out << " <value ";
|
out << " <value ";
|
||||||
if (it->isTokValue())
|
switch (it->valueType) {
|
||||||
out << "tokvalue=\"" << it->tokvalue << '\"';
|
case ValueFlow::Value::INT:
|
||||||
else if (it->isIntValue())
|
|
||||||
out << "intvalue=\"" << it->intvalue << '\"';
|
out << "intvalue=\"" << it->intvalue << '\"';
|
||||||
|
break;
|
||||||
|
case ValueFlow::Value::TOK:
|
||||||
|
out << "tokvalue=\"" << it->tokvalue << '\"';
|
||||||
|
break;
|
||||||
|
case ValueFlow::Value::FLOAT:
|
||||||
|
out << "floatvalue=\"" << it->floatValue << '\"';
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (it->condition)
|
if (it->condition)
|
||||||
out << " condition-line=\"" << it->condition->linenr() << '\"';
|
out << " condition-line=\"" << it->condition->linenr() << '\"';
|
||||||
if (it->isKnown())
|
if (it->isKnown())
|
||||||
|
@ -1341,10 +1348,17 @@ void Token::printValueFlow(bool xml, std::ostream &out) const
|
||||||
else {
|
else {
|
||||||
if (it != tok->values.begin())
|
if (it != tok->values.begin())
|
||||||
out << ",";
|
out << ",";
|
||||||
if (it->isTokValue())
|
switch (it->valueType) {
|
||||||
out << it->tokvalue->str();
|
case ValueFlow::Value::INT:
|
||||||
else if (it->isIntValue())
|
|
||||||
out << it->intvalue;
|
out << it->intvalue;
|
||||||
|
break;
|
||||||
|
case ValueFlow::Value::TOK:
|
||||||
|
out << it->tokvalue->str();
|
||||||
|
break;
|
||||||
|
case ValueFlow::Value::FLOAT:
|
||||||
|
out << it->floatValue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (xml)
|
if (xml)
|
||||||
|
|
|
@ -598,6 +598,12 @@ static Token * valueFlowSetConstantValue(const Token *tok, const Settings *setti
|
||||||
ValueFlow::Value value(MathLib::toLongNumber(tok->str()));
|
ValueFlow::Value value(MathLib::toLongNumber(tok->str()));
|
||||||
value.setKnown();
|
value.setKnown();
|
||||||
setTokenValue(const_cast<Token *>(tok), value, settings);
|
setTokenValue(const_cast<Token *>(tok), value, settings);
|
||||||
|
} else if (tok->isNumber() && MathLib::isFloat(tok->str())) {
|
||||||
|
ValueFlow::Value value;
|
||||||
|
value.valueType = ValueFlow::Value::FLOAT;
|
||||||
|
value.floatValue = MathLib::toDoubleNumber(tok->str());
|
||||||
|
value.setKnown();
|
||||||
|
setTokenValue(const_cast<Token *>(tok), value, settings);
|
||||||
} else if (tok->enumerator() && tok->enumerator()->value_known) {
|
} else if (tok->enumerator() && tok->enumerator()->value_known) {
|
||||||
ValueFlow::Value value(tok->enumerator()->value);
|
ValueFlow::Value value(tok->enumerator()->value);
|
||||||
value.setKnown();
|
value.setKnown();
|
||||||
|
|
|
@ -33,8 +33,8 @@ class Settings;
|
||||||
namespace ValueFlow {
|
namespace ValueFlow {
|
||||||
class CPPCHECKLIB Value {
|
class CPPCHECKLIB Value {
|
||||||
public:
|
public:
|
||||||
explicit Value(long long val = 0) : valueType(INT), intvalue(val), tokvalue(nullptr), varvalue(val), condition(0), varId(0U), conditional(false), inconclusive(false), defaultArg(false), valueKind(ValueKind::Possible) {}
|
explicit Value(long long val = 0) : valueType(INT), intvalue(val), tokvalue(nullptr), floatValue(0.0), varvalue(val), condition(0), varId(0U), conditional(false), inconclusive(false), defaultArg(false), valueKind(ValueKind::Possible) {}
|
||||||
Value(const Token *c, long long val) : valueType(INT), intvalue(val), tokvalue(nullptr), varvalue(val), condition(c), varId(0U), conditional(false), inconclusive(false), defaultArg(false), valueKind(ValueKind::Possible) {}
|
Value(const Token *c, long long val) : valueType(INT), intvalue(val), tokvalue(nullptr), floatValue(0.0), varvalue(val), condition(c), varId(0U), conditional(false), inconclusive(false), defaultArg(false), valueKind(ValueKind::Possible) {}
|
||||||
|
|
||||||
bool operator==(const Value &rhs) const {
|
bool operator==(const Value &rhs) const {
|
||||||
if (valueType != rhs.valueType)
|
if (valueType != rhs.valueType)
|
||||||
|
@ -48,6 +48,11 @@ namespace ValueFlow {
|
||||||
if (tokvalue != rhs.tokvalue)
|
if (tokvalue != rhs.tokvalue)
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
case FLOAT:
|
||||||
|
// TODO: Write some better comparison
|
||||||
|
if (floatValue > rhs.floatValue || floatValue < rhs.floatValue)
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
return varvalue == rhs.varvalue &&
|
return varvalue == rhs.varvalue &&
|
||||||
|
@ -59,13 +64,16 @@ namespace ValueFlow {
|
||||||
valueKind == rhs.valueKind;
|
valueKind == rhs.valueKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ValueType { INT, TOK } valueType;
|
enum ValueType { INT, TOK, FLOAT } valueType;
|
||||||
bool isIntValue() const {
|
bool isIntValue() const {
|
||||||
return valueType == INT;
|
return valueType == INT;
|
||||||
}
|
}
|
||||||
bool isTokValue() const {
|
bool isTokValue() const {
|
||||||
return valueType == TOK;
|
return valueType == TOK;
|
||||||
}
|
}
|
||||||
|
bool isFloatValue() const {
|
||||||
|
return valueType == FLOAT;
|
||||||
|
}
|
||||||
|
|
||||||
/** int value */
|
/** int value */
|
||||||
long long intvalue;
|
long long intvalue;
|
||||||
|
@ -73,6 +81,9 @@ namespace ValueFlow {
|
||||||
/** token value - the token that has the value. this is used for pointer aliases, strings, etc. */
|
/** token value - the token that has the value. this is used for pointer aliases, strings, etc. */
|
||||||
const Token *tokvalue;
|
const Token *tokvalue;
|
||||||
|
|
||||||
|
/** float value */
|
||||||
|
double floatValue;
|
||||||
|
|
||||||
/** For calculated values - variable value that calculated value depends on */
|
/** For calculated values - variable value that calculated value depends on */
|
||||||
long long varvalue;
|
long long varvalue;
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
class TestValueFlow : public TestFixture {
|
class TestValueFlow : public TestFixture {
|
||||||
public:
|
public:
|
||||||
|
@ -91,7 +91,7 @@ private:
|
||||||
if (tok->str() == "x" && tok->linenr() == linenr) {
|
if (tok->str() == "x" && tok->linenr() == linenr) {
|
||||||
std::list<ValueFlow::Value>::const_iterator it;
|
std::list<ValueFlow::Value>::const_iterator it;
|
||||||
for (it = tok->values.begin(); it != tok->values.end(); ++it) {
|
for (it = tok->values.begin(); it != tok->values.end(); ++it) {
|
||||||
if (it->intvalue == value && !it->tokvalue)
|
if (it->isIntValue() && it->intvalue == value)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ private:
|
||||||
if (tok->str() == "x" && tok->linenr() == linenr) {
|
if (tok->str() == "x" && tok->linenr() == linenr) {
|
||||||
std::list<ValueFlow::Value>::const_iterator it;
|
std::list<ValueFlow::Value>::const_iterator it;
|
||||||
for (it = tok->values.begin(); it != tok->values.end(); ++it) {
|
for (it = tok->values.begin(); it != tok->values.end(); ++it) {
|
||||||
if (Token::simpleMatch(it->tokvalue, value))
|
if (it->isTokValue() && Token::simpleMatch(it->tokvalue, value))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ private:
|
||||||
if (tok->str() == "x" && tok->linenr() == linenr) {
|
if (tok->str() == "x" && tok->linenr() == linenr) {
|
||||||
std::list<ValueFlow::Value>::const_iterator it;
|
std::list<ValueFlow::Value>::const_iterator it;
|
||||||
for (it = tok->values.begin(); it != tok->values.end(); ++it) {
|
for (it = tok->values.begin(); it != tok->values.end(); ++it) {
|
||||||
if (it->intvalue == value && !it->tokvalue && it->condition)
|
if (it->isIntValue() && it->intvalue == value && it->condition)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -162,11 +162,12 @@ private:
|
||||||
|
|
||||||
ValueFlow::Value valueOfTok(const char code[], const char tokstr[]) {
|
ValueFlow::Value valueOfTok(const char code[], const char tokstr[]) {
|
||||||
std::list<ValueFlow::Value> values = tokenValues(code, tokstr);
|
std::list<ValueFlow::Value> values = tokenValues(code, tokstr);
|
||||||
return values.size() == 1U && !values.front().tokvalue ? values.front() : ValueFlow::Value();
|
return values.size() == 1U && !values.front().isTokValue() ? values.front() : ValueFlow::Value();
|
||||||
}
|
}
|
||||||
|
|
||||||
void valueFlowNumber() {
|
void valueFlowNumber() {
|
||||||
ASSERT_EQUALS(123, valueOfTok("x=123;", "123").intvalue);
|
ASSERT_EQUALS(123, valueOfTok("x=123;", "123").intvalue);
|
||||||
|
ASSERT(std::fabs(valueOfTok("x=0.5;", "0.5").floatValue - 0.5f) < 0.1f);
|
||||||
ASSERT_EQUALS(10, valueOfTok("enum {A=10,B=15}; x=A+0;", "+").intvalue);
|
ASSERT_EQUALS(10, valueOfTok("enum {A=10,B=15}; x=A+0;", "+").intvalue);
|
||||||
ASSERT_EQUALS(0, valueOfTok("x=false;", "false").intvalue);
|
ASSERT_EQUALS(0, valueOfTok("x=false;", "false").intvalue);
|
||||||
ASSERT_EQUALS(1, valueOfTok("x=true;", "true").intvalue);
|
ASSERT_EQUALS(1, valueOfTok("x=true;", "true").intvalue);
|
||||||
|
|
Loading…
Reference in New Issue