Refactoring: Convert ValueType to enum class (#3005)

This commit is contained in:
Rikard Falkeborn 2021-01-02 09:30:00 +01:00 committed by GitHub
parent 3445a958d5
commit d19454b935
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 89 additions and 89 deletions

View File

@ -93,7 +93,7 @@ std::string CTU::FileInfo::FunctionCall::toXmlString() const
out << "<function-call" out << "<function-call"
<< toBaseXmlString() << toBaseXmlString()
<< " " << ATTR_CALL_ARGEXPR << "=\"" << callArgumentExpression << "\"" << " " << ATTR_CALL_ARGEXPR << "=\"" << callArgumentExpression << "\""
<< " " << ATTR_CALL_ARGVALUETYPE << "=\"" << callValueType << "\"" << " " << ATTR_CALL_ARGVALUETYPE << "=\"" << static_cast<int>(callValueType) << "\""
<< " " << ATTR_CALL_ARGVALUE << "=\"" << callArgValue << "\""; << " " << ATTR_CALL_ARGVALUE << "=\"" << callArgValue << "\"";
if (warning) if (warning)
out << " " << ATTR_WARNING << "=\"true\""; out << " " << ATTR_WARNING << "=\"true\"";

View File

@ -1669,37 +1669,37 @@ void Token::printValueFlow(bool xml, std::ostream &out) const
if (xml) { if (xml) {
out << " <value "; out << " <value ";
switch (value.valueType) { switch (value.valueType) {
case ValueFlow::Value::INT: case ValueFlow::Value::ValueType::INT:
if (tok->valueType() && tok->valueType()->sign == ValueType::UNSIGNED) if (tok->valueType() && tok->valueType()->sign == ValueType::UNSIGNED)
out << "intvalue=\"" << (MathLib::biguint)value.intvalue << '\"'; out << "intvalue=\"" << (MathLib::biguint)value.intvalue << '\"';
else else
out << "intvalue=\"" << value.intvalue << '\"'; out << "intvalue=\"" << value.intvalue << '\"';
break; break;
case ValueFlow::Value::TOK: case ValueFlow::Value::ValueType::TOK:
out << "tokvalue=\"" << value.tokvalue << '\"'; out << "tokvalue=\"" << value.tokvalue << '\"';
break; break;
case ValueFlow::Value::FLOAT: case ValueFlow::Value::ValueType::FLOAT:
out << "floatvalue=\"" << value.floatValue << '\"'; out << "floatvalue=\"" << value.floatValue << '\"';
break; break;
case ValueFlow::Value::MOVED: case ValueFlow::Value::ValueType::MOVED:
out << "movedvalue=\"" << ValueFlow::Value::toString(value.moveKind) << '\"'; out << "movedvalue=\"" << ValueFlow::Value::toString(value.moveKind) << '\"';
break; break;
case ValueFlow::Value::UNINIT: case ValueFlow::Value::ValueType::UNINIT:
out << "uninit=\"1\""; out << "uninit=\"1\"";
break; break;
case ValueFlow::Value::BUFFER_SIZE: case ValueFlow::Value::ValueType::BUFFER_SIZE:
out << "buffer-size=\"" << value.intvalue << "\""; out << "buffer-size=\"" << value.intvalue << "\"";
break; break;
case ValueFlow::Value::CONTAINER_SIZE: case ValueFlow::Value::ValueType::CONTAINER_SIZE:
out << "container-size=\"" << value.intvalue << '\"'; out << "container-size=\"" << value.intvalue << '\"';
break; break;
case ValueFlow::Value::ITERATOR_START: case ValueFlow::Value::ValueType::ITERATOR_START:
out << "iterator-start=\"" << value.intvalue << '\"'; out << "iterator-start=\"" << value.intvalue << '\"';
break; break;
case ValueFlow::Value::ITERATOR_END: case ValueFlow::Value::ValueType::ITERATOR_END:
out << "iterator-end=\"" << value.intvalue << '\"'; out << "iterator-end=\"" << value.intvalue << '\"';
break; break;
case ValueFlow::Value::LIFETIME: case ValueFlow::Value::ValueType::LIFETIME:
out << "lifetime=\"" << value.tokvalue << '\"'; out << "lifetime=\"" << value.tokvalue << '\"';
break; break;
} }
@ -1726,35 +1726,35 @@ void Token::printValueFlow(bool xml, std::ostream &out) const
if (value.bound == ValueFlow::Value::Bound::Upper) if (value.bound == ValueFlow::Value::Bound::Upper)
out << "<="; out << "<=";
switch (value.valueType) { switch (value.valueType) {
case ValueFlow::Value::INT: case ValueFlow::Value::ValueType::INT:
if (tok->valueType() && tok->valueType()->sign == ValueType::UNSIGNED) if (tok->valueType() && tok->valueType()->sign == ValueType::UNSIGNED)
out << (MathLib::biguint)value.intvalue; out << (MathLib::biguint)value.intvalue;
else else
out << value.intvalue; out << value.intvalue;
break; break;
case ValueFlow::Value::TOK: case ValueFlow::Value::ValueType::TOK:
out << value.tokvalue->str(); out << value.tokvalue->str();
break; break;
case ValueFlow::Value::FLOAT: case ValueFlow::Value::ValueType::FLOAT:
out << value.floatValue; out << value.floatValue;
break; break;
case ValueFlow::Value::MOVED: case ValueFlow::Value::ValueType::MOVED:
out << ValueFlow::Value::toString(value.moveKind); out << ValueFlow::Value::toString(value.moveKind);
break; break;
case ValueFlow::Value::UNINIT: case ValueFlow::Value::ValueType::UNINIT:
out << "Uninit"; out << "Uninit";
break; break;
case ValueFlow::Value::BUFFER_SIZE: case ValueFlow::Value::ValueType::BUFFER_SIZE:
case ValueFlow::Value::CONTAINER_SIZE: case ValueFlow::Value::ValueType::CONTAINER_SIZE:
out << "size=" << value.intvalue; out << "size=" << value.intvalue;
break; break;
case ValueFlow::Value::ITERATOR_START: case ValueFlow::Value::ValueType::ITERATOR_START:
out << "start=" << value.intvalue; out << "start=" << value.intvalue;
break; break;
case ValueFlow::Value::ITERATOR_END: case ValueFlow::Value::ValueType::ITERATOR_END:
out << "end=" << value.intvalue; out << "end=" << value.intvalue;
break; break;
case ValueFlow::Value::LIFETIME: case ValueFlow::Value::ValueType::LIFETIME:
out << "lifetime=" << value.tokvalue->str(); out << "lifetime=" << value.tokvalue->str();
break; break;
} }

View File

@ -263,7 +263,7 @@ static bool isEscapeScope(const Token* tok, TokenList * tokenlist, bool unknown
static ValueFlow::Value castValue(ValueFlow::Value value, const ValueType::Sign sign, nonneg int bit) static ValueFlow::Value castValue(ValueFlow::Value value, const ValueType::Sign sign, nonneg int bit)
{ {
if (value.isFloatValue()) { if (value.isFloatValue()) {
value.valueType = ValueFlow::Value::INT; value.valueType = ValueFlow::Value::ValueType::INT;
if (value.floatValue >= std::numeric_limits<int>::min() && value.floatValue <= std::numeric_limits<int>::max()) { if (value.floatValue >= std::numeric_limits<int>::min() && value.floatValue <= std::numeric_limits<int>::max()) {
value.intvalue = value.floatValue; value.intvalue = value.floatValue;
} else { // don't perform UB } else { // don't perform UB
@ -431,7 +431,7 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
// cast.. // cast..
if (const Token *castType = getCastTypeStartToken(parent)) { if (const Token *castType = getCastTypeStartToken(parent)) {
if (((tok->valueType() == nullptr && value.isImpossible()) || astIsPointer(tok)) && value.valueType == ValueFlow::Value::INT && if (((tok->valueType() == nullptr && value.isImpossible()) || astIsPointer(tok)) && value.valueType == ValueFlow::Value::ValueType::INT &&
Token::simpleMatch(parent->astOperand1(), "dynamic_cast")) Token::simpleMatch(parent->astOperand1(), "dynamic_cast"))
return; return;
const ValueType &valueType = ValueType::parseDecl(castType, settings); const ValueType &valueType = ValueType::parseDecl(castType, settings);
@ -546,7 +546,7 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
if (value1.isTokValue() || value2.isTokValue()) if (value1.isTokValue() || value2.isTokValue())
break; break;
if (value1.isFloatValue() || value2.isFloatValue()) { if (value1.isFloatValue() || value2.isFloatValue()) {
result.valueType = ValueFlow::Value::FLOAT; result.valueType = ValueFlow::Value::ValueType::FLOAT;
result.floatValue = floatValue1 + floatValue2; result.floatValue = floatValue1 + floatValue2;
} else { } else {
result.intvalue = value1.intvalue + value2.intvalue; result.intvalue = value1.intvalue + value2.intvalue;
@ -557,7 +557,7 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
if (value1.isTokValue() || value2.isTokValue()) if (value1.isTokValue() || value2.isTokValue())
break; break;
if (value1.isFloatValue() || value2.isFloatValue()) { if (value1.isFloatValue() || value2.isFloatValue()) {
result.valueType = ValueFlow::Value::FLOAT; result.valueType = ValueFlow::Value::ValueType::FLOAT;
result.floatValue = floatValue1 - floatValue2; result.floatValue = floatValue1 - floatValue2;
} else { } else {
// Avoid overflow // Avoid overflow
@ -575,7 +575,7 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
if (value1.isTokValue() || value2.isTokValue()) if (value1.isTokValue() || value2.isTokValue())
break; break;
if (value1.isFloatValue() || value2.isFloatValue()) { if (value1.isFloatValue() || value2.isFloatValue()) {
result.valueType = ValueFlow::Value::FLOAT; result.valueType = ValueFlow::Value::ValueType::FLOAT;
result.floatValue = floatValue1 * floatValue2; result.floatValue = floatValue1 * floatValue2;
} else { } else {
result.intvalue = value1.intvalue * value2.intvalue; result.intvalue = value1.intvalue * value2.intvalue;
@ -586,7 +586,7 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
if (value1.isTokValue() || value2.isTokValue() || value2.intvalue == 0) if (value1.isTokValue() || value2.isTokValue() || value2.intvalue == 0)
break; break;
if (value1.isFloatValue() || value2.isFloatValue()) { if (value1.isFloatValue() || value2.isFloatValue()) {
result.valueType = ValueFlow::Value::FLOAT; result.valueType = ValueFlow::Value::ValueType::FLOAT;
result.floatValue = floatValue1 / floatValue2; result.floatValue = floatValue1 / floatValue2;
} else { } else {
result.intvalue = value1.intvalue / value2.intvalue; result.intvalue = value1.intvalue / value2.intvalue;
@ -905,7 +905,7 @@ static Token * valueFlowSetConstantValue(Token *tok, const Settings *settings, b
setTokenValue(tok, value, settings); setTokenValue(tok, value, settings);
} else if (tok->isNumber() && MathLib::isFloat(tok->str())) { } else if (tok->isNumber() && MathLib::isFloat(tok->str())) {
ValueFlow::Value value; ValueFlow::Value value;
value.valueType = ValueFlow::Value::FLOAT; value.valueType = ValueFlow::Value::ValueType::FLOAT;
value.floatValue = MathLib::toDoubleNumber(tok->str()); value.floatValue = MathLib::toDoubleNumber(tok->str());
if (!tok->isTemplateArg()) if (!tok->isTemplateArg())
value.setKnown(); value.setKnown();
@ -1085,7 +1085,7 @@ static void valueFlowString(TokenList *tokenlist)
for (Token *tok = tokenlist->front(); tok; tok = tok->next()) { for (Token *tok = tokenlist->front(); tok; tok = tok->next()) {
if (tok->tokType() == Token::eString) { if (tok->tokType() == Token::eString) {
ValueFlow::Value strvalue; ValueFlow::Value strvalue;
strvalue.valueType = ValueFlow::Value::TOK; strvalue.valueType = ValueFlow::Value::ValueType::TOK;
strvalue.tokvalue = tok; strvalue.tokvalue = tok;
strvalue.setKnown(); strvalue.setKnown();
setTokenValue(tok, strvalue, tokenlist->getSettings()); setTokenValue(tok, strvalue, tokenlist->getSettings());
@ -1103,7 +1103,7 @@ static void valueFlowArray(TokenList *tokenlist)
const std::map<int, const Token *>::const_iterator it = constantArrays.find(tok->varId()); const std::map<int, const Token *>::const_iterator it = constantArrays.find(tok->varId());
if (it != constantArrays.end()) { if (it != constantArrays.end()) {
ValueFlow::Value value; ValueFlow::Value value;
value.valueType = ValueFlow::Value::TOK; value.valueType = ValueFlow::Value::ValueType::TOK;
value.tokvalue = it->second; value.tokvalue = it->second;
value.setKnown(); value.setKnown();
setTokenValue(tok, value, tokenlist->getSettings()); setTokenValue(tok, value, tokenlist->getSettings());
@ -1118,7 +1118,7 @@ static void valueFlowArray(TokenList *tokenlist)
tok->astParent()->astOperand1()->variable() && tok->astParent()->astOperand1()->variable() &&
tok->astParent()->astOperand1()->variable()->isPointer()) { tok->astParent()->astOperand1()->variable()->isPointer()) {
ValueFlow::Value value; ValueFlow::Value value;
value.valueType = ValueFlow::Value::TOK; value.valueType = ValueFlow::Value::ValueType::TOK;
value.tokvalue = tok; value.tokvalue = tok;
value.setKnown(); value.setKnown();
setTokenValue(tok, value, tokenlist->getSettings()); setTokenValue(tok, value, tokenlist->getSettings());
@ -1220,7 +1220,7 @@ static void valueFlowPointerAlias(TokenList *tokenlist)
continue; continue;
ValueFlow::Value value; ValueFlow::Value value;
value.valueType = ValueFlow::Value::TOK; value.valueType = ValueFlow::Value::ValueType::TOK;
value.tokvalue = tok; value.tokvalue = tok;
setTokenValue(tok, value, tokenlist->getSettings()); setTokenValue(tok, value, tokenlist->getSettings());
} }
@ -3229,7 +3229,7 @@ struct LifetimeStore {
er.emplace_back(argtok, message); er.emplace_back(argtok, message);
ValueFlow::Value value; ValueFlow::Value value;
value.valueType = ValueFlow::Value::LIFETIME; value.valueType = ValueFlow::Value::ValueType::LIFETIME;
value.lifetimeScope = ValueFlow::Value::LifetimeScope::Local; value.lifetimeScope = ValueFlow::Value::LifetimeScope::Local;
value.tokvalue = lt.token; value.tokvalue = lt.token;
value.errorPath = std::move(er); value.errorPath = std::move(er);
@ -3263,7 +3263,7 @@ struct LifetimeStore {
const Variable *var = getLifetimeVariable(argtok, er); const Variable *var = getLifetimeVariable(argtok, er);
if (var && var->isArgument()) { if (var && var->isArgument()) {
ValueFlow::Value value; ValueFlow::Value value;
value.valueType = ValueFlow::Value::LIFETIME; value.valueType = ValueFlow::Value::ValueType::LIFETIME;
value.lifetimeScope = ValueFlow::Value::LifetimeScope::Argument; value.lifetimeScope = ValueFlow::Value::LifetimeScope::Argument;
value.tokvalue = var->nameToken(); value.tokvalue = var->nameToken();
value.errorPath = er; value.errorPath = er;
@ -3293,7 +3293,7 @@ struct LifetimeStore {
er.insert(er.end(), errorPath.begin(), errorPath.end()); er.insert(er.end(), errorPath.begin(), errorPath.end());
ValueFlow::Value value; ValueFlow::Value value;
value.valueType = ValueFlow::Value::LIFETIME; value.valueType = ValueFlow::Value::ValueType::LIFETIME;
value.lifetimeScope = v.lifetimeScope; value.lifetimeScope = v.lifetimeScope;
value.path = v.path; value.path = v.path;
value.tokvalue = lt.token; value.tokvalue = lt.token;
@ -3992,7 +3992,7 @@ static std::list<ValueFlow::Value> truncateValues(std::list<ValueFlow::Value> va
for (ValueFlow::Value &value : values) { for (ValueFlow::Value &value : values) {
if (value.isFloatValue()) { if (value.isFloatValue()) {
value.intvalue = value.floatValue; value.intvalue = value.floatValue;
value.valueType = ValueFlow::Value::INT; value.valueType = ValueFlow::Value::ValueType::INT;
} }
if (value.isIntValue() && sz > 0 && sz < 8) { if (value.isIntValue() && sz > 0 && sz < 8) {
@ -4066,7 +4066,7 @@ static void valueFlowAfterAssign(TokenList *tokenlist, SymbolDatabase* symboldat
// Remove container size if its not a container // Remove container size if its not a container
if (!astIsContainer(tok->astOperand2())) if (!astIsContainer(tok->astOperand2()))
values.remove_if([&](const ValueFlow::Value& value) { values.remove_if([&](const ValueFlow::Value& value) {
return value.valueType == ValueFlow::Value::CONTAINER_SIZE; return value.valueType == ValueFlow::Value::ValueType::CONTAINER_SIZE;
}); });
if (values.empty()) if (values.empty())
continue; continue;
@ -4534,7 +4534,7 @@ static const ValueFlow::Value* proveNotEqual(const std::list<ValueFlow::Value>&
{ {
const ValueFlow::Value* result = nullptr; const ValueFlow::Value* result = nullptr;
for (const ValueFlow::Value& value : values) { for (const ValueFlow::Value& value : values) {
if (value.valueType != ValueFlow::Value::INT) if (value.valueType != ValueFlow::Value::ValueType::INT)
continue; continue;
if (result && !isInBounds(value, result->intvalue)) if (result && !isInBounds(value, result->intvalue))
continue; continue;
@ -5167,7 +5167,7 @@ static bool evaluate(const Token *expr, const std::vector<std::list<ValueFlow::V
if (argvalue.isTokValue() && argvalue.tokvalue->tokType() == Token::eString) { if (argvalue.isTokValue() && argvalue.tokvalue->tokType() == Token::eString) {
ValueFlow::Value res(argvalue); // copy all "inconclusive", "condition", etc attributes ValueFlow::Value res(argvalue); // copy all "inconclusive", "condition", etc attributes
// set return value.. // set return value..
res.valueType = ValueFlow::Value::INT; res.valueType = ValueFlow::Value::ValueType::INT;
res.tokvalue = nullptr; res.tokvalue = nullptr;
res.intvalue = Token::getStrLength(argvalue.tokvalue); res.intvalue = Token::getStrLength(argvalue.tokvalue);
result->emplace_back(std::move(res)); result->emplace_back(std::move(res));
@ -5549,7 +5549,7 @@ static void valueFlowUninit(TokenList *tokenlist, SymbolDatabase * /*symbolDatab
ValueFlow::Value uninitValue; ValueFlow::Value uninitValue;
uninitValue.setKnown(); uninitValue.setKnown();
uninitValue.valueType = ValueFlow::Value::UNINIT; uninitValue.valueType = ValueFlow::Value::ValueType::UNINIT;
uninitValue.tokvalue = vardecl; uninitValue.tokvalue = vardecl;
std::list<ValueFlow::Value> values; std::list<ValueFlow::Value> values;
values.push_back(uninitValue); values.push_back(uninitValue);
@ -5923,10 +5923,10 @@ static void valueFlowIterators(TokenList *tokenlist, const Settings *settings)
ValueFlow::Value v(0); ValueFlow::Value v(0);
v.setKnown(); v.setKnown();
if (yield == Library::Container::Yield::START_ITERATOR) { if (yield == Library::Container::Yield::START_ITERATOR) {
v.valueType = ValueFlow::Value::ITERATOR_START; v.valueType = ValueFlow::Value::ValueType::ITERATOR_START;
setTokenValue(tok->astParent()->tokAt(2), v, settings); setTokenValue(tok->astParent()->tokAt(2), v, settings);
} else if (yield == Library::Container::Yield::END_ITERATOR) { } else if (yield == Library::Container::Yield::END_ITERATOR) {
v.valueType = ValueFlow::Value::ITERATOR_END; v.valueType = ValueFlow::Value::ValueType::ITERATOR_END;
setTokenValue(tok->astParent()->tokAt(2), v, settings); setTokenValue(tok->astParent()->tokAt(2), v, settings);
} }
} }
@ -6157,8 +6157,8 @@ struct ContainerConditionHandler : ConditionHandler {
vartok = vartok->tokAt(-3); vartok = vartok->tokAt(-3);
if (!isContainerSize(vartok)) if (!isContainerSize(vartok))
return cond; return cond;
true_value.valueType = ValueFlow::Value::CONTAINER_SIZE; true_value.valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE;
false_value.valueType = ValueFlow::Value::CONTAINER_SIZE; false_value.valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE;
cond.true_values.push_back(true_value); cond.true_values.push_back(true_value);
cond.false_values.push_back(false_value); cond.false_values.push_back(false_value);
cond.vartok = vartok; cond.vartok = vartok;
@ -6508,7 +6508,7 @@ static void valueFlowUnknownFunctionReturn(TokenList *tokenlist, const Settings
} }
ValueFlow::Value::Value(const Token* c, long long val) ValueFlow::Value::Value(const Token* c, long long val)
: valueType(INT), : valueType(ValueType::INT),
bound(Bound::Point), bound(Bound::Point),
intvalue(val), intvalue(val),
tokvalue(nullptr), tokvalue(nullptr),
@ -6538,24 +6538,24 @@ void ValueFlow::Value::assumeCondition(const Token* tok)
std::string ValueFlow::Value::infoString() const std::string ValueFlow::Value::infoString() const
{ {
switch (valueType) { switch (valueType) {
case INT: case ValueType::INT:
return MathLib::toString(intvalue); return MathLib::toString(intvalue);
case TOK: case ValueType::TOK:
return tokvalue->str(); return tokvalue->str();
case FLOAT: case ValueType::FLOAT:
return MathLib::toString(floatValue); return MathLib::toString(floatValue);
case MOVED: case ValueType::MOVED:
return "<Moved>"; return "<Moved>";
case UNINIT: case ValueType::UNINIT:
return "<Uninit>"; return "<Uninit>";
case BUFFER_SIZE: case ValueType::BUFFER_SIZE:
case CONTAINER_SIZE: case ValueType::CONTAINER_SIZE:
return "size=" + MathLib::toString(intvalue); return "size=" + MathLib::toString(intvalue);
case ITERATOR_START: case ValueType::ITERATOR_START:
return "start=" + MathLib::toString(intvalue); return "start=" + MathLib::toString(intvalue);
case ITERATOR_END: case ValueType::ITERATOR_END:
return "end=" + MathLib::toString(intvalue); return "end=" + MathLib::toString(intvalue);
case LIFETIME: case ValueType::LIFETIME:
return "lifetime=" + tokvalue->str(); return "lifetime=" + tokvalue->str();
} }
throw InternalError(nullptr, "Invalid ValueFlow Value type"); throw InternalError(nullptr, "Invalid ValueFlow Value type");

View File

@ -190,7 +190,7 @@ namespace ValueFlow {
std::string infoString() const; std::string infoString() const;
enum ValueType { INT, TOK, FLOAT, MOVED, UNINIT, CONTAINER_SIZE, LIFETIME, BUFFER_SIZE, ITERATOR_START, ITERATOR_END } valueType; enum class ValueType { INT, TOK, FLOAT, MOVED, UNINIT, CONTAINER_SIZE, LIFETIME, BUFFER_SIZE, ITERATOR_START, ITERATOR_END } valueType;
bool isIntValue() const { bool isIntValue() const {
return valueType == ValueType::INT; return valueType == ValueType::INT;
} }

View File

@ -1127,7 +1127,7 @@ private:
// pointer points at buffer that is 2 bytes // pointer points at buffer that is 2 bytes
ValueFlow::Value v2(2); ValueFlow::Value v2(2);
v2.valueType = ValueFlow::Value::BUFFER_SIZE; v2.valueType = ValueFlow::Value::ValueType::BUFFER_SIZE;
v2.setKnown(); v2.setKnown();
Token token; Token token;

View File

@ -428,7 +428,7 @@ private:
" if (a) x = \"123\";\n" " if (a) x = \"123\";\n"
" return x;\n" " return x;\n"
"}"; "}";
ASSERT_EQUALS(true, testValueOfX(code, 4, "\"123\"", ValueFlow::Value::TOK)); ASSERT_EQUALS(true, testValueOfX(code, 4, "\"123\"", ValueFlow::Value::ValueType::TOK));
// valueFlowSubFunction // valueFlowSubFunction
code = "void dostuff(const char *x) {\n" code = "void dostuff(const char *x) {\n"
@ -436,7 +436,7 @@ private:
"}\n" "}\n"
"\n" "\n"
"void test() { dostuff(\"abc\"); }"; "void test() { dostuff(\"abc\"); }";
ASSERT_EQUALS(true, testValueOfX(code, 2, "\"abc\"", ValueFlow::Value::TOK)); ASSERT_EQUALS(true, testValueOfX(code, 2, "\"abc\"", ValueFlow::Value::ValueType::TOK));
} }
void valueFlowPointerAlias() { void valueFlowPointerAlias() {
@ -449,7 +449,7 @@ private:
" if (a) x = &ret[0];\n" " if (a) x = &ret[0];\n"
" return x;\n" " return x;\n"
"}"; "}";
ASSERT_EQUALS(true, testValueOfX(code, 5, "& ret [ 0 ]", ValueFlow::Value::TOK)); ASSERT_EQUALS(true, testValueOfX(code, 5, "& ret [ 0 ]", ValueFlow::Value::ValueType::TOK));
// dead pointer // dead pointer
code = "void f() {\n" code = "void f() {\n"
@ -457,7 +457,7 @@ private:
" if (cond) { int i; x = &i; }\n" " if (cond) { int i; x = &i; }\n"
" *x = 0;\n" // <- x can point at i " *x = 0;\n" // <- x can point at i
"}"; "}";
ASSERT_EQUALS(true, testValueOfX(code, 4, "& i", ValueFlow::Value::TOK)); ASSERT_EQUALS(true, testValueOfX(code, 4, "& i", ValueFlow::Value::ValueType::TOK));
code = "void f() {\n" code = "void f() {\n"
" struct X *x;\n" " struct X *x;\n"
@ -483,14 +483,14 @@ private:
" auto x = [&]() { return a + 1; };\n" " auto x = [&]() { return a + 1; };\n"
" auto b = x;\n" " auto b = x;\n"
"}\n"; "}\n";
ASSERT_EQUALS(true, testValueOfX(code, 4, "a + 1", ValueFlow::Value::LIFETIME)); ASSERT_EQUALS(true, testValueOfX(code, 4, "a + 1", ValueFlow::Value::ValueType::LIFETIME));
code = "void f() {\n" code = "void f() {\n"
" int a = 1;\n" " int a = 1;\n"
" auto x = [=]() { return a + 1; };\n" " auto x = [=]() { return a + 1; };\n"
" auto b = x;\n" " auto b = x;\n"
"}\n"; "}\n";
ASSERT_EQUALS(false, testValueOfX(code, 4, "a ;", ValueFlow::Value::LIFETIME)); ASSERT_EQUALS(false, testValueOfX(code, 4, "a ;", ValueFlow::Value::ValueType::LIFETIME));
code = "void f(int v) {\n" code = "void f(int v) {\n"
" int a = v;\n" " int a = v;\n"
@ -498,14 +498,14 @@ private:
" auto x = [=]() { return p + 1; };\n" " auto x = [=]() { return p + 1; };\n"
" auto b = x;\n" " auto b = x;\n"
"}\n"; "}\n";
ASSERT_EQUALS(true, testValueOfX(code, 5, "a ;", ValueFlow::Value::LIFETIME)); ASSERT_EQUALS(true, testValueOfX(code, 5, "a ;", ValueFlow::Value::ValueType::LIFETIME));
code = "void f() {\n" code = "void f() {\n"
" std::vector<int> v;\n" " std::vector<int> v;\n"
" auto x = v.begin();\n" " auto x = v.begin();\n"
" auto it = x;\n" " auto it = x;\n"
"}\n"; "}\n";
ASSERT_EQUALS(true, testValueOfX(code, 4, "v . begin", ValueFlow::Value::LIFETIME)); ASSERT_EQUALS(true, testValueOfX(code, 4, "v . begin", ValueFlow::Value::ValueType::LIFETIME));
code = "void f() {\n" code = "void f() {\n"
" int i = 0;\n" " int i = 0;\n"
@ -523,26 +523,26 @@ private:
" const int x[] = {43,23,12};\n" " const int x[] = {43,23,12};\n"
" return x;\n" " return x;\n"
"}"; "}";
ASSERT_EQUALS(true, testValueOfX(code, 3U, "{ 43 , 23 , 12 }", ValueFlow::Value::TOK)); ASSERT_EQUALS(true, testValueOfX(code, 3U, "{ 43 , 23 , 12 }", ValueFlow::Value::ValueType::TOK));
code = "void f() {\n" code = "void f() {\n"
" const char x[] = \"abcd\";\n" " const char x[] = \"abcd\";\n"
" return x;\n" " return x;\n"
"}"; "}";
ASSERT_EQUALS(true, testValueOfX(code, 3U, "\"abcd\"", ValueFlow::Value::TOK)); ASSERT_EQUALS(true, testValueOfX(code, 3U, "\"abcd\"", ValueFlow::Value::ValueType::TOK));
code = "void f() {\n" code = "void f() {\n"
" char x[32] = \"abcd\";\n" " char x[32] = \"abcd\";\n"
" return x;\n" " return x;\n"
"}"; "}";
TODO_ASSERT_EQUALS(true, false, testValueOfX(code, 3U, "\"abcd\"", ValueFlow::Value::TOK)); TODO_ASSERT_EQUALS(true, false, testValueOfX(code, 3U, "\"abcd\"", ValueFlow::Value::ValueType::TOK));
code = "void f() {\n" code = "void f() {\n"
" int a[10];\n" " int a[10];\n"
" int *x = a;\n" // <- a value is a " int *x = a;\n" // <- a value is a
" *x = 0;\n" // .. => x value is a " *x = 0;\n" // .. => x value is a
"}"; "}";
ASSERT_EQUALS(true, testValueOfX(code, 4, "a", ValueFlow::Value::TOK)); ASSERT_EQUALS(true, testValueOfX(code, 4, "a", ValueFlow::Value::ValueType::TOK));
code = "char f() {\n" code = "char f() {\n"
" const char *x = \"abcd\";\n" " const char *x = \"abcd\";\n"
@ -1729,7 +1729,7 @@ private:
" a = ((x[0] == 'U') ?\n" " a = ((x[0] == 'U') ?\n"
" x[1] : 0);\n" // <- x is not "" " x[1] : 0);\n" // <- x is not ""
"}"; "}";
ASSERT_EQUALS(false, testValueOfX(code, 4U, "\"\"", ValueFlow::Value::TOK)); ASSERT_EQUALS(false, testValueOfX(code, 4U, "\"\"", ValueFlow::Value::ValueType::TOK));
code = "void f() {\n" // #6973 code = "void f() {\n" // #6973
" char *x = getenv (\"LC_ALL\");\n" " char *x = getenv (\"LC_ALL\");\n"
@ -1742,10 +1742,10 @@ private:
" x[2] ))\n" // x can't be "" " x[2] ))\n" // x can't be ""
" {}\n" " {}\n"
"}\n"; "}\n";
ASSERT_EQUALS(true, testValueOfX(code, 6U, "\"\"", ValueFlow::Value::TOK)); ASSERT_EQUALS(true, testValueOfX(code, 6U, "\"\"", ValueFlow::Value::ValueType::TOK));
ASSERT_EQUALS(false, testValueOfX(code, 7U, "\"\"", ValueFlow::Value::TOK)); ASSERT_EQUALS(false, testValueOfX(code, 7U, "\"\"", ValueFlow::Value::ValueType::TOK));
ASSERT_EQUALS(false, testValueOfX(code, 8U, "\"\"", ValueFlow::Value::TOK)); ASSERT_EQUALS(false, testValueOfX(code, 8U, "\"\"", ValueFlow::Value::ValueType::TOK));
ASSERT_EQUALS(false, testValueOfX(code, 9U, "\"\"", ValueFlow::Value::TOK)); ASSERT_EQUALS(false, testValueOfX(code, 9U, "\"\"", ValueFlow::Value::ValueType::TOK));
code = "void f() {\n" // #7599 code = "void f() {\n" // #7599
" t *x = 0;\n" " t *x = 0;\n"
@ -4691,27 +4691,27 @@ private:
" ints.clear();\n" " ints.clear();\n"
" ints.front();\n" " ints.front();\n"
"}"; "}";
ASSERT_EQUALS("", isKnownContainerSizeValue(tokenValues(code, "ints . front", ValueFlow::Value::CONTAINER_SIZE), 0)); ASSERT_EQUALS("", isKnownContainerSizeValue(tokenValues(code, "ints . front", ValueFlow::Value::ValueType::CONTAINER_SIZE), 0));
code = "void f(const std::vector<int> &ints) {\n" code = "void f(const std::vector<int> &ints) {\n"
" ints.resize(3);\n" " ints.resize(3);\n"
" ints.front();\n" " ints.front();\n"
"}"; "}";
ASSERT_EQUALS("", isKnownContainerSizeValue(tokenValues(code, "ints . front", ValueFlow::Value::CONTAINER_SIZE), 3)); ASSERT_EQUALS("", isKnownContainerSizeValue(tokenValues(code, "ints . front", ValueFlow::Value::ValueType::CONTAINER_SIZE), 3));
code = "void f(const std::vector<int> &ints) {\n" code = "void f(const std::vector<int> &ints) {\n"
" ints.resize(3);\n" " ints.resize(3);\n"
" ints.push_back(3);\n" " ints.push_back(3);\n"
" ints.front();\n" " ints.front();\n"
"}"; "}";
ASSERT_EQUALS("", isKnownContainerSizeValue(tokenValues(code, "ints . front", ValueFlow::Value::CONTAINER_SIZE), 4)); ASSERT_EQUALS("", isKnownContainerSizeValue(tokenValues(code, "ints . front", ValueFlow::Value::ValueType::CONTAINER_SIZE), 4));
code = "void f(const std::vector<int> &ints) {\n" code = "void f(const std::vector<int> &ints) {\n"
" ints.resize(3);\n" " ints.resize(3);\n"
" ints.pop_back();\n" " ints.pop_back();\n"
" ints.front();\n" " ints.front();\n"
"}"; "}";
ASSERT_EQUALS("", isKnownContainerSizeValue(tokenValues(code, "ints . front", ValueFlow::Value::CONTAINER_SIZE), 2)); ASSERT_EQUALS("", isKnownContainerSizeValue(tokenValues(code, "ints . front", ValueFlow::Value::ValueType::CONTAINER_SIZE), 2));
code = "int f(bool b) {\n" code = "int f(bool b) {\n"
" std::map<int, int> m;\n" " std::map<int, int> m;\n"
@ -4719,7 +4719,7 @@ private:
" m[0] = 1;\n" " m[0] = 1;\n"
" return m.at(0);\n" " return m.at(0);\n"
"}\n"; "}\n";
ASSERT_EQUALS("", isPossibleContainerSizeValue(tokenValues(code, "m . at", ValueFlow::Value::CONTAINER_SIZE), 0)); ASSERT_EQUALS("", isPossibleContainerSizeValue(tokenValues(code, "m . at", ValueFlow::Value::ValueType::CONTAINER_SIZE), 0));
code = "struct Base {\n" code = "struct Base {\n"
" virtual bool GetString(std::string &) const { return false; }\n" " virtual bool GetString(std::string &) const { return false; }\n"
@ -4741,14 +4741,14 @@ private:
" ints.front();\n" " ints.front();\n"
"}"; "}";
ASSERT_EQUALS("", ASSERT_EQUALS("",
isKnownContainerSizeValue(tokenValues(code, "ints . front", ValueFlow::Value::CONTAINER_SIZE), 0)); isKnownContainerSizeValue(tokenValues(code, "ints . front", ValueFlow::Value::ValueType::CONTAINER_SIZE), 0));
code = "void f() {\n" code = "void f() {\n"
" std::vector<int> ints{1};\n" " std::vector<int> ints{1};\n"
" ints.front();\n" " ints.front();\n"
"}"; "}";
ASSERT_EQUALS("", ASSERT_EQUALS("",
isKnownContainerSizeValue(tokenValues(code, "ints . front", ValueFlow::Value::CONTAINER_SIZE), 1)); isKnownContainerSizeValue(tokenValues(code, "ints . front", ValueFlow::Value::ValueType::CONTAINER_SIZE), 1));
code = "void f() {\n" code = "void f() {\n"
" std::vector<int> ints{1};\n" " std::vector<int> ints{1};\n"
@ -4756,21 +4756,21 @@ private:
" ints2.front();\n" " ints2.front();\n"
"}"; "}";
ASSERT_EQUALS( ASSERT_EQUALS(
"", isKnownContainerSizeValue(tokenValues(code, "ints2 . front", ValueFlow::Value::CONTAINER_SIZE), 1)); "", isKnownContainerSizeValue(tokenValues(code, "ints2 . front", ValueFlow::Value::ValueType::CONTAINER_SIZE), 1));
code = "void f() {\n" code = "void f() {\n"
" std::vector<int> ints = {};\n" " std::vector<int> ints = {};\n"
" ints.front();\n" " ints.front();\n"
"}"; "}";
ASSERT_EQUALS("", ASSERT_EQUALS("",
isKnownContainerSizeValue(tokenValues(code, "ints . front", ValueFlow::Value::CONTAINER_SIZE), 0)); isKnownContainerSizeValue(tokenValues(code, "ints . front", ValueFlow::Value::ValueType::CONTAINER_SIZE), 0));
code = "void f() {\n" code = "void f() {\n"
" std::vector<int> ints = {1};\n" " std::vector<int> ints = {1};\n"
" ints.front();\n" " ints.front();\n"
"}"; "}";
ASSERT_EQUALS("", ASSERT_EQUALS("",
isKnownContainerSizeValue(tokenValues(code, "ints . front", ValueFlow::Value::CONTAINER_SIZE), 1)); isKnownContainerSizeValue(tokenValues(code, "ints . front", ValueFlow::Value::ValueType::CONTAINER_SIZE), 1));
} }
void valueFlowDynamicBufferSize() { void valueFlowDynamicBufferSize() {
@ -4783,34 +4783,34 @@ private:
" void* x = malloc(10);\n" " void* x = malloc(10);\n"
" return x;\n" " return x;\n"
"}"; "}";
ASSERT_EQUALS(true, testValueOfX(code, 3U, 10, ValueFlow::Value::BUFFER_SIZE)); ASSERT_EQUALS(true, testValueOfX(code, 3U, 10, ValueFlow::Value::ValueType::BUFFER_SIZE));
code = "void* f() {\n" code = "void* f() {\n"
" void* x = calloc(4, 5);\n" " void* x = calloc(4, 5);\n"
" return x;\n" " return x;\n"
"}"; "}";
ASSERT_EQUALS(true, testValueOfX(code, 3U, 20, ValueFlow::Value::BUFFER_SIZE)); ASSERT_EQUALS(true, testValueOfX(code, 3U, 20, ValueFlow::Value::ValueType::BUFFER_SIZE));
code = "void* f() {\n" code = "void* f() {\n"
" const char* y = \"abcd\";\n" " const char* y = \"abcd\";\n"
" const char* x = strdup(y);\n" " const char* x = strdup(y);\n"
" return x;\n" " return x;\n"
"}"; "}";
ASSERT_EQUALS(true, testValueOfX(code, 4U, 5, ValueFlow::Value::BUFFER_SIZE)); ASSERT_EQUALS(true, testValueOfX(code, 4U, 5, ValueFlow::Value::ValueType::BUFFER_SIZE));
code = "void* f() {\n" code = "void* f() {\n"
" void* y = malloc(10);\n" " void* y = malloc(10);\n"
" void* x = realloc(y, 20);\n" " void* x = realloc(y, 20);\n"
" return x;\n" " return x;\n"
"}"; "}";
ASSERT_EQUALS(true, testValueOfX(code, 4U, 20, ValueFlow::Value::BUFFER_SIZE)); ASSERT_EQUALS(true, testValueOfX(code, 4U, 20, ValueFlow::Value::ValueType::BUFFER_SIZE));
code = "void* f() {\n" code = "void* f() {\n"
" void* y = calloc(10, 4);\n" " void* y = calloc(10, 4);\n"
" void* x = reallocarray(y, 20, 5);\n" " void* x = reallocarray(y, 20, 5);\n"
" return x;\n" " return x;\n"
"}"; "}";
ASSERT_EQUALS(true, testValueOfX(code, 4U, 100, ValueFlow::Value::BUFFER_SIZE)); ASSERT_EQUALS(true, testValueOfX(code, 4U, 100, ValueFlow::Value::ValueType::BUFFER_SIZE));
} }
void valueFlowSafeFunctionParameterValues() { void valueFlowSafeFunctionParameterValues() {