ValueFlow: Template arguments have 'possible' values
This commit is contained in:
parent
bbeff99cc3
commit
6fd157e93b
|
@ -670,21 +670,25 @@ static Token * valueFlowSetConstantValue(const Token *tok, const Settings *setti
|
||||||
{
|
{
|
||||||
if ((tok->isNumber() && MathLib::isInt(tok->str())) || (tok->tokType() == Token::eChar)) {
|
if ((tok->isNumber() && MathLib::isInt(tok->str())) || (tok->tokType() == Token::eChar)) {
|
||||||
ValueFlow::Value value(MathLib::toLongNumber(tok->str()));
|
ValueFlow::Value value(MathLib::toLongNumber(tok->str()));
|
||||||
value.setKnown();
|
if (!tok->isTemplateArg())
|
||||||
|
value.setKnown();
|
||||||
setTokenValue(const_cast<Token *>(tok), value, settings);
|
setTokenValue(const_cast<Token *>(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::FLOAT;
|
||||||
value.floatValue = MathLib::toDoubleNumber(tok->str());
|
value.floatValue = MathLib::toDoubleNumber(tok->str());
|
||||||
value.setKnown();
|
if (!tok->isTemplateArg())
|
||||||
|
value.setKnown();
|
||||||
setTokenValue(const_cast<Token *>(tok), value, settings);
|
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();
|
if (!tok->isTemplateArg())
|
||||||
|
value.setKnown();
|
||||||
setTokenValue(const_cast<Token *>(tok), value, settings);
|
setTokenValue(const_cast<Token *>(tok), value, settings);
|
||||||
} else if (tok->str() == "NULL" || (cpp && tok->str() == "nullptr")) {
|
} else if (tok->str() == "NULL" || (cpp && tok->str() == "nullptr")) {
|
||||||
ValueFlow::Value value(0);
|
ValueFlow::Value value(0);
|
||||||
value.setKnown();
|
if (!tok->isTemplateArg())
|
||||||
|
value.setKnown();
|
||||||
setTokenValue(const_cast<Token *>(tok), value, settings);
|
setTokenValue(const_cast<Token *>(tok), value, settings);
|
||||||
} else if (Token::simpleMatch(tok, "sizeof (")) {
|
} else if (Token::simpleMatch(tok, "sizeof (")) {
|
||||||
const Token *tok2 = tok->tokAt(2);
|
const Token *tok2 = tok->tokAt(2);
|
||||||
|
@ -695,7 +699,7 @@ static Token * valueFlowSetConstantValue(const Token *tok, const Settings *setti
|
||||||
size = getSizeOfType(type, settings);
|
size = getSizeOfType(type, settings);
|
||||||
}
|
}
|
||||||
ValueFlow::Value value(size);
|
ValueFlow::Value value(size);
|
||||||
if (settings->platformType != cppcheck::Platform::Unspecified)
|
if (!tok2->isTemplateArg() && settings->platformType != cppcheck::Platform::Unspecified)
|
||||||
value.setKnown();
|
value.setKnown();
|
||||||
setTokenValue(const_cast<Token *>(tok), value, settings);
|
setTokenValue(const_cast<Token *>(tok), value, settings);
|
||||||
setTokenValue(const_cast<Token *>(tok->next()), value, settings);
|
setTokenValue(const_cast<Token *>(tok->next()), value, settings);
|
||||||
|
@ -708,7 +712,7 @@ static Token * valueFlowSetConstantValue(const Token *tok, const Settings *setti
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ValueFlow::Value value(size);
|
ValueFlow::Value value(size);
|
||||||
if (settings->platformType != cppcheck::Platform::Unspecified)
|
if (!tok2->isTemplateArg() && settings->platformType != cppcheck::Platform::Unspecified)
|
||||||
value.setKnown();
|
value.setKnown();
|
||||||
setTokenValue(const_cast<Token *>(tok), value, settings);
|
setTokenValue(const_cast<Token *>(tok), value, settings);
|
||||||
setTokenValue(const_cast<Token *>(tok->next()), value, settings);
|
setTokenValue(const_cast<Token *>(tok->next()), value, settings);
|
||||||
|
@ -724,7 +728,7 @@ static Token * valueFlowSetConstantValue(const Token *tok, const Settings *setti
|
||||||
sz1->variable()->dimensionKnown(0) &&
|
sz1->variable()->dimensionKnown(0) &&
|
||||||
(Token::Match(sz2, "* %varid% )", varid1) || Token::Match(sz2, "%varid% [ 0 ] )", varid1))) {
|
(Token::Match(sz2, "* %varid% )", varid1) || Token::Match(sz2, "%varid% [ 0 ] )", varid1))) {
|
||||||
ValueFlow::Value value(sz1->variable()->dimension(0));
|
ValueFlow::Value value(sz1->variable()->dimension(0));
|
||||||
if (settings->platformType != cppcheck::Platform::Unspecified)
|
if (!tok2->isTemplateArg() && settings->platformType != cppcheck::Platform::Unspecified)
|
||||||
value.setKnown();
|
value.setKnown();
|
||||||
setTokenValue(const_cast<Token *>(tok->tokAt(4)), value, settings);
|
setTokenValue(const_cast<Token *>(tok->tokAt(4)), value, settings);
|
||||||
}
|
}
|
||||||
|
@ -732,42 +736,42 @@ static Token * valueFlowSetConstantValue(const Token *tok, const Settings *setti
|
||||||
const ValueType &vt = ValueType::parseDecl(tok2,settings);
|
const ValueType &vt = ValueType::parseDecl(tok2,settings);
|
||||||
if (vt.pointer) {
|
if (vt.pointer) {
|
||||||
ValueFlow::Value value(settings->sizeof_pointer);
|
ValueFlow::Value value(settings->sizeof_pointer);
|
||||||
if (settings->platformType != cppcheck::Platform::Unspecified)
|
if (!tok2->isTemplateArg() && settings->platformType != cppcheck::Platform::Unspecified)
|
||||||
value.setKnown();
|
value.setKnown();
|
||||||
setTokenValue(const_cast<Token *>(tok->next()), value, settings);
|
setTokenValue(const_cast<Token *>(tok->next()), value, settings);
|
||||||
} else if (vt.type == ValueType::Type::CHAR) {
|
} else if (vt.type == ValueType::Type::CHAR) {
|
||||||
ValueFlow::Value value(1);
|
ValueFlow::Value value(1);
|
||||||
if (settings->platformType != cppcheck::Platform::Unspecified)
|
if (!tok2->isTemplateArg() && settings->platformType != cppcheck::Platform::Unspecified)
|
||||||
value.setKnown();
|
value.setKnown();
|
||||||
setTokenValue(const_cast<Token *>(tok->next()), value, settings);
|
setTokenValue(const_cast<Token *>(tok->next()), value, settings);
|
||||||
} else if (vt.type == ValueType::Type::SHORT) {
|
} else if (vt.type == ValueType::Type::SHORT) {
|
||||||
ValueFlow::Value value(settings->sizeof_short);
|
ValueFlow::Value value(settings->sizeof_short);
|
||||||
if (settings->platformType != cppcheck::Platform::Unspecified)
|
if (!tok2->isTemplateArg() && settings->platformType != cppcheck::Platform::Unspecified)
|
||||||
value.setKnown();
|
value.setKnown();
|
||||||
setTokenValue(const_cast<Token *>(tok->next()), value, settings);
|
setTokenValue(const_cast<Token *>(tok->next()), value, settings);
|
||||||
} else if (vt.type == ValueType::Type::INT) {
|
} else if (vt.type == ValueType::Type::INT) {
|
||||||
ValueFlow::Value value(settings->sizeof_int);
|
ValueFlow::Value value(settings->sizeof_int);
|
||||||
if (settings->platformType != cppcheck::Platform::Unspecified)
|
if (!tok2->isTemplateArg() && settings->platformType != cppcheck::Platform::Unspecified)
|
||||||
value.setKnown();
|
value.setKnown();
|
||||||
setTokenValue(const_cast<Token *>(tok->next()), value, settings);
|
setTokenValue(const_cast<Token *>(tok->next()), value, settings);
|
||||||
} else if (vt.type == ValueType::Type::LONG) {
|
} else if (vt.type == ValueType::Type::LONG) {
|
||||||
ValueFlow::Value value(settings->sizeof_long);
|
ValueFlow::Value value(settings->sizeof_long);
|
||||||
if (settings->platformType != cppcheck::Platform::Unspecified)
|
if (!tok2->isTemplateArg() && settings->platformType != cppcheck::Platform::Unspecified)
|
||||||
value.setKnown();
|
value.setKnown();
|
||||||
setTokenValue(const_cast<Token *>(tok->next()), value, settings);
|
setTokenValue(const_cast<Token *>(tok->next()), value, settings);
|
||||||
} else if (vt.type == ValueType::Type::LONGLONG) {
|
} else if (vt.type == ValueType::Type::LONGLONG) {
|
||||||
ValueFlow::Value value(settings->sizeof_long_long);
|
ValueFlow::Value value(settings->sizeof_long_long);
|
||||||
if (settings->platformType != cppcheck::Platform::Unspecified)
|
if (!tok2->isTemplateArg() && settings->platformType != cppcheck::Platform::Unspecified)
|
||||||
value.setKnown();
|
value.setKnown();
|
||||||
setTokenValue(const_cast<Token *>(tok->next()), value, settings);
|
setTokenValue(const_cast<Token *>(tok->next()), value, settings);
|
||||||
} else if (vt.type == ValueType::Type::FLOAT) {
|
} else if (vt.type == ValueType::Type::FLOAT) {
|
||||||
ValueFlow::Value value(settings->sizeof_float);
|
ValueFlow::Value value(settings->sizeof_float);
|
||||||
if (settings->platformType != cppcheck::Platform::Unspecified)
|
if (!tok2->isTemplateArg() && settings->platformType != cppcheck::Platform::Unspecified)
|
||||||
value.setKnown();
|
value.setKnown();
|
||||||
setTokenValue(const_cast<Token *>(tok->next()), value, settings);
|
setTokenValue(const_cast<Token *>(tok->next()), value, settings);
|
||||||
} else if (vt.type == ValueType::Type::DOUBLE) {
|
} else if (vt.type == ValueType::Type::DOUBLE) {
|
||||||
ValueFlow::Value value(settings->sizeof_double);
|
ValueFlow::Value value(settings->sizeof_double);
|
||||||
if (settings->platformType != cppcheck::Platform::Unspecified)
|
if (!tok2->isTemplateArg() && settings->platformType != cppcheck::Platform::Unspecified)
|
||||||
value.setKnown();
|
value.setKnown();
|
||||||
setTokenValue(const_cast<Token *>(tok->next()), value, settings);
|
setTokenValue(const_cast<Token *>(tok->next()), value, settings);
|
||||||
}
|
}
|
||||||
|
@ -789,13 +793,15 @@ static void valueFlowNumber(TokenList *tokenlist)
|
||||||
for (Token *tok = tokenlist->front(); tok; tok = tok->next()) {
|
for (Token *tok = tokenlist->front(); tok; tok = tok->next()) {
|
||||||
if (tok->isName() && !tok->varId() && Token::Match(tok, "false|true")) {
|
if (tok->isName() && !tok->varId() && Token::Match(tok, "false|true")) {
|
||||||
ValueFlow::Value value(tok->str() == "true");
|
ValueFlow::Value value(tok->str() == "true");
|
||||||
value.setKnown();
|
if (!tok->isTemplateArg())
|
||||||
|
value.setKnown();
|
||||||
setTokenValue(tok, value, tokenlist->getSettings());
|
setTokenValue(tok, value, tokenlist->getSettings());
|
||||||
} else if (Token::Match(tok, "[(,] NULL [,)]")) {
|
} else if (Token::Match(tok, "[(,] NULL [,)]")) {
|
||||||
// NULL function parameters are not simplified in the
|
// NULL function parameters are not simplified in the
|
||||||
// normal tokenlist
|
// normal tokenlist
|
||||||
ValueFlow::Value value(0);
|
ValueFlow::Value value(0);
|
||||||
value.setKnown();
|
if (!tok->isTemplateArg())
|
||||||
|
value.setKnown();
|
||||||
setTokenValue(tok->next(), value, tokenlist->getSettings());
|
setTokenValue(tok->next(), value, tokenlist->getSettings());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2622,6 +2622,13 @@ private:
|
||||||
ASSERT_EQUALS(true, testValueOfX(code, 4U, 6));
|
ASSERT_EQUALS(true, testValueOfX(code, 4U, 6));
|
||||||
ASSERT_EQUALS(false, testValueOfX(code, 4U, 7));
|
ASSERT_EQUALS(false, testValueOfX(code, 4U, 7));
|
||||||
ASSERT(value.isKnown());
|
ASSERT(value.isKnown());
|
||||||
|
|
||||||
|
// template parameters are not known
|
||||||
|
code = "template <int X> void f() { a = X; }\n"
|
||||||
|
"f<1>();";
|
||||||
|
value = valueOfTok(code, "1");
|
||||||
|
ASSERT_EQUALS(1, value.intvalue);
|
||||||
|
ASSERT_EQUALS(false, value.isKnown());
|
||||||
}
|
}
|
||||||
|
|
||||||
void valueFlowSizeofForwardDeclaredEnum() {
|
void valueFlowSizeofForwardDeclaredEnum() {
|
||||||
|
|
Loading…
Reference in New Issue