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) {
|
||||
if (xml) {
|
||||
out << " <value ";
|
||||
if (it->isTokValue())
|
||||
out << "tokvalue=\"" << it->tokvalue << '\"';
|
||||
else if (it->isIntValue())
|
||||
switch (it->valueType) {
|
||||
case ValueFlow::Value::INT:
|
||||
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)
|
||||
out << " condition-line=\"" << it->condition->linenr() << '\"';
|
||||
if (it->isKnown())
|
||||
|
@ -1341,10 +1348,17 @@ void Token::printValueFlow(bool xml, std::ostream &out) const
|
|||
else {
|
||||
if (it != tok->values.begin())
|
||||
out << ",";
|
||||
if (it->isTokValue())
|
||||
out << it->tokvalue->str();
|
||||
else if (it->isIntValue())
|
||||
switch (it->valueType) {
|
||||
case ValueFlow::Value::INT:
|
||||
out << it->intvalue;
|
||||
break;
|
||||
case ValueFlow::Value::TOK:
|
||||
out << it->tokvalue->str();
|
||||
break;
|
||||
case ValueFlow::Value::FLOAT:
|
||||
out << it->floatValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (xml)
|
||||
|
|
|
@ -598,6 +598,12 @@ static Token * valueFlowSetConstantValue(const Token *tok, const Settings *setti
|
|||
ValueFlow::Value value(MathLib::toLongNumber(tok->str()));
|
||||
value.setKnown();
|
||||
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) {
|
||||
ValueFlow::Value value(tok->enumerator()->value);
|
||||
value.setKnown();
|
||||
|
|
|
@ -33,8 +33,8 @@ class Settings;
|
|||
namespace ValueFlow {
|
||||
class CPPCHECKLIB Value {
|
||||
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) {}
|
||||
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) {}
|
||||
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), floatValue(0.0), varvalue(val), condition(c), varId(0U), conditional(false), inconclusive(false), defaultArg(false), valueKind(ValueKind::Possible) {}
|
||||
|
||||
bool operator==(const Value &rhs) const {
|
||||
if (valueType != rhs.valueType)
|
||||
|
@ -48,6 +48,11 @@ namespace ValueFlow {
|
|||
if (tokvalue != rhs.tokvalue)
|
||||
return false;
|
||||
break;
|
||||
case FLOAT:
|
||||
// TODO: Write some better comparison
|
||||
if (floatValue > rhs.floatValue || floatValue < rhs.floatValue)
|
||||
return false;
|
||||
break;
|
||||
};
|
||||
|
||||
return varvalue == rhs.varvalue &&
|
||||
|
@ -59,13 +64,16 @@ namespace ValueFlow {
|
|||
valueKind == rhs.valueKind;
|
||||
}
|
||||
|
||||
enum ValueType { INT, TOK } valueType;
|
||||
enum ValueType { INT, TOK, FLOAT } valueType;
|
||||
bool isIntValue() const {
|
||||
return valueType == INT;
|
||||
}
|
||||
bool isTokValue() const {
|
||||
return valueType == TOK;
|
||||
}
|
||||
bool isFloatValue() const {
|
||||
return valueType == FLOAT;
|
||||
}
|
||||
|
||||
/** int value */
|
||||
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. */
|
||||
const Token *tokvalue;
|
||||
|
||||
/** float value */
|
||||
double floatValue;
|
||||
|
||||
/** For calculated values - variable value that calculated value depends on */
|
||||
long long varvalue;
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
class TestValueFlow : public TestFixture {
|
||||
public:
|
||||
|
@ -91,7 +91,7 @@ private:
|
|||
if (tok->str() == "x" && tok->linenr() == linenr) {
|
||||
std::list<ValueFlow::Value>::const_iterator 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;
|
||||
}
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ private:
|
|||
if (tok->str() == "x" && tok->linenr() == linenr) {
|
||||
std::list<ValueFlow::Value>::const_iterator 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;
|
||||
}
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ private:
|
|||
if (tok->str() == "x" && tok->linenr() == linenr) {
|
||||
std::list<ValueFlow::Value>::const_iterator 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;
|
||||
}
|
||||
}
|
||||
|
@ -162,11 +162,12 @@ private:
|
|||
|
||||
ValueFlow::Value valueOfTok(const char code[], const char 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() {
|
||||
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(0, valueOfTok("x=false;", "false").intvalue);
|
||||
ASSERT_EQUALS(1, valueOfTok("x=true;", "true").intvalue);
|
||||
|
|
Loading…
Reference in New Issue