* Fix #11649 Hang in setTokenValue() on huge array * Fix function call
This commit is contained in:
parent
023e79b6c2
commit
4fdcb0c784
|
@ -604,6 +604,7 @@ static ValueFlow::Value truncateImplicitConversion(Token* parent, const ValueFlo
|
||||||
static void setTokenValue(Token* tok,
|
static void setTokenValue(Token* tok,
|
||||||
ValueFlow::Value value,
|
ValueFlow::Value value,
|
||||||
const Settings* settings,
|
const Settings* settings,
|
||||||
|
bool isInitList = false,
|
||||||
SourceLocation loc = SourceLocation::current())
|
SourceLocation loc = SourceLocation::current())
|
||||||
{
|
{
|
||||||
// Skip setting values that are too big since its ambiguous
|
// Skip setting values that are too big since its ambiguous
|
||||||
|
@ -627,7 +628,7 @@ static void setTokenValue(Token* tok,
|
||||||
if (!parent)
|
if (!parent)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (Token::simpleMatch(parent, ",") && astIsRHS(tok)) {
|
if (!isInitList && Token::simpleMatch(parent, ",") && astIsRHS(tok)) {
|
||||||
const Token* callParent = findParent(parent, [](const Token* p) {
|
const Token* callParent = findParent(parent, [](const Token* p) {
|
||||||
return !Token::simpleMatch(p, ",");
|
return !Token::simpleMatch(p, ",");
|
||||||
});
|
});
|
||||||
|
@ -1137,7 +1138,7 @@ size_t ValueFlow::getSizeOf(const ValueType &vt, const Settings *settings)
|
||||||
static bool getMinMaxValues(const ValueType* vt, const cppcheck::Platform& platform, MathLib::bigint& minValue, MathLib::bigint& maxValue);
|
static bool getMinMaxValues(const ValueType* vt, const cppcheck::Platform& platform, MathLib::bigint& minValue, MathLib::bigint& maxValue);
|
||||||
|
|
||||||
// Handle various constants..
|
// Handle various constants..
|
||||||
static Token * valueFlowSetConstantValue(Token *tok, const Settings *settings, bool cpp)
|
static Token * valueFlowSetConstantValue(Token *tok, const Settings *settings, bool cpp, bool isInitList = false)
|
||||||
{
|
{
|
||||||
if ((tok->isNumber() && MathLib::isInt(tok->str())) || (tok->tokType() == Token::eChar)) {
|
if ((tok->isNumber() && MathLib::isInt(tok->str())) || (tok->tokType() == Token::eChar)) {
|
||||||
try {
|
try {
|
||||||
|
@ -1151,7 +1152,7 @@ static Token * valueFlowSetConstantValue(Token *tok, const Settings *settings, b
|
||||||
ValueFlow::Value value(signedValue);
|
ValueFlow::Value value(signedValue);
|
||||||
if (!tok->isTemplateArg())
|
if (!tok->isTemplateArg())
|
||||||
value.setKnown();
|
value.setKnown();
|
||||||
setTokenValue(tok, std::move(value), settings);
|
setTokenValue(tok, std::move(value), settings, isInitList);
|
||||||
} catch (const std::exception & /*e*/) {
|
} catch (const std::exception & /*e*/) {
|
||||||
// Bad character literal
|
// Bad character literal
|
||||||
}
|
}
|
||||||
|
@ -1161,17 +1162,17 @@ static Token * valueFlowSetConstantValue(Token *tok, const Settings *settings, b
|
||||||
value.floatValue = MathLib::toDoubleNumber(tok->str());
|
value.floatValue = MathLib::toDoubleNumber(tok->str());
|
||||||
if (!tok->isTemplateArg())
|
if (!tok->isTemplateArg())
|
||||||
value.setKnown();
|
value.setKnown();
|
||||||
setTokenValue(tok, std::move(value), settings);
|
setTokenValue(tok, std::move(value), settings, isInitList);
|
||||||
} 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);
|
||||||
if (!tok->isTemplateArg())
|
if (!tok->isTemplateArg())
|
||||||
value.setKnown();
|
value.setKnown();
|
||||||
setTokenValue(tok, std::move(value), settings);
|
setTokenValue(tok, std::move(value), settings, isInitList);
|
||||||
} 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);
|
||||||
if (!tok->isTemplateArg())
|
if (!tok->isTemplateArg())
|
||||||
value.setKnown();
|
value.setKnown();
|
||||||
setTokenValue(tok, std::move(value), settings);
|
setTokenValue(tok, std::move(value), settings, isInitList);
|
||||||
} else if (Token::simpleMatch(tok, "sizeof (")) {
|
} else if (Token::simpleMatch(tok, "sizeof (")) {
|
||||||
if (tok->next()->astOperand2() && !tok->next()->astOperand2()->isLiteral() && tok->next()->astOperand2()->valueType() &&
|
if (tok->next()->astOperand2() && !tok->next()->astOperand2()->isLiteral() && tok->next()->astOperand2()->valueType() &&
|
||||||
(tok->next()->astOperand2()->valueType()->pointer == 0 || // <- TODO this is a bailout, abort when there are array->pointer conversions
|
(tok->next()->astOperand2()->valueType()->pointer == 0 || // <- TODO this is a bailout, abort when there are array->pointer conversions
|
||||||
|
@ -1339,8 +1340,16 @@ static Token * valueFlowSetConstantValue(Token *tok, const Settings *settings, b
|
||||||
|
|
||||||
static void valueFlowNumber(TokenList *tokenlist, const Settings* settings)
|
static void valueFlowNumber(TokenList *tokenlist, const Settings* settings)
|
||||||
{
|
{
|
||||||
|
bool isInitList = false;
|
||||||
|
const Token* endInit{};
|
||||||
for (Token *tok = tokenlist->front(); tok;) {
|
for (Token *tok = tokenlist->front(); tok;) {
|
||||||
tok = valueFlowSetConstantValue(tok, settings, tokenlist->isCPP());
|
if (!isInitList && tok->str() == "{" && Token::simpleMatch(tok->astOperand1(), ",")) {
|
||||||
|
isInitList = true;
|
||||||
|
endInit = tok->link();
|
||||||
|
}
|
||||||
|
tok = valueFlowSetConstantValue(tok, settings, tokenlist->isCPP(), isInitList);
|
||||||
|
if (isInitList && tok == endInit)
|
||||||
|
isInitList = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tokenlist->isCPP()) {
|
if (tokenlist->isCPP()) {
|
||||||
|
|
Loading…
Reference in New Issue