replace some pattern matching with variable lookup in checkGlobalAndLocalVariable
This commit is contained in:
parent
4656eba34c
commit
93495613dd
|
@ -1224,6 +1224,23 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo
|
||||||
|
|
||||||
void CheckBufferOverrun::checkGlobalAndLocalVariable()
|
void CheckBufferOverrun::checkGlobalAndLocalVariable()
|
||||||
{
|
{
|
||||||
|
// check all known fixed size arrays first by just looking them up
|
||||||
|
for (size_t i = 1; i <= _tokenizer->varIdCount(); i++)
|
||||||
|
{
|
||||||
|
const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(i);
|
||||||
|
if (var && var->isArray() && var->dimension(0) > 0)
|
||||||
|
{
|
||||||
|
ArrayInfo arrayInfo(var, _tokenizer);
|
||||||
|
const Token *tok = var->nameToken();
|
||||||
|
while (tok && tok->str() != ";")
|
||||||
|
tok = tok->next();
|
||||||
|
if (!tok)
|
||||||
|
break;
|
||||||
|
checkScope(tok, arrayInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// find all dynamically allocated arrays next by parsing the token stream
|
||||||
// Count { and } when parsing all tokens
|
// Count { and } when parsing all tokens
|
||||||
int indentlevel = 0;
|
int indentlevel = 0;
|
||||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
||||||
|
@ -1254,87 +1271,7 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
|
||||||
"Check (BufferOverrun::checkGlobalAndLocalVariable)",
|
"Check (BufferOverrun::checkGlobalAndLocalVariable)",
|
||||||
tok->progressValue());
|
tok->progressValue());
|
||||||
|
|
||||||
ArrayInfo arrayInfo;
|
if (indentlevel > 0 && Token::Match(tok, "[*;{}] %var% = new %type% [ %num% ]"))
|
||||||
if (arrayInfo.declare(tok, *_tokenizer))
|
|
||||||
{
|
|
||||||
while (tok && tok->str() != ";")
|
|
||||||
tok = tok->next();
|
|
||||||
if (!tok)
|
|
||||||
break;
|
|
||||||
checkScope(tok, arrayInfo);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Token::Match(tok, "%type% *| %var% [ %var% ] [;=]"))
|
|
||||||
{
|
|
||||||
// varpos : position for variable token
|
|
||||||
unsigned char varpos = 1;
|
|
||||||
if (tok->next()->str() == "*")
|
|
||||||
++varpos;
|
|
||||||
|
|
||||||
// make sure the variable is defined
|
|
||||||
if (tok->tokAt(varpos + 2)->varId() == 0)
|
|
||||||
continue; // FIXME we loose the check for negative index when we bail
|
|
||||||
|
|
||||||
// get maximum size from type
|
|
||||||
// find where this type is defined
|
|
||||||
const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(tok->tokAt(varpos + 2)->varId());
|
|
||||||
|
|
||||||
// make sure it is in the database
|
|
||||||
if (!var)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// get type token
|
|
||||||
const Token *index_type = var->typeEndToken();
|
|
||||||
|
|
||||||
if (index_type->str() == "char")
|
|
||||||
{
|
|
||||||
if (index_type->isUnsigned())
|
|
||||||
size = UCHAR_MAX + 1;
|
|
||||||
else if (index_type->isSigned())
|
|
||||||
size = SCHAR_MAX + 1;
|
|
||||||
else
|
|
||||||
size = CHAR_MAX + 1;
|
|
||||||
}
|
|
||||||
else if (index_type->str() == "short")
|
|
||||||
{
|
|
||||||
if (index_type->isUnsigned())
|
|
||||||
size = USHRT_MAX + 1;
|
|
||||||
else
|
|
||||||
size = SHRT_MAX + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkScope assumes size is signed int so we limit the following sizes to INT_MAX
|
|
||||||
else if (index_type->str() == "int")
|
|
||||||
{
|
|
||||||
if (index_type->isUnsigned())
|
|
||||||
size = INT_MAX; // should be UINT_MAX + 1U;
|
|
||||||
else
|
|
||||||
size = INT_MAX; // should be INT_MAX + 1U;
|
|
||||||
}
|
|
||||||
else if (index_type->str() == "long")
|
|
||||||
{
|
|
||||||
if (index_type->isUnsigned())
|
|
||||||
{
|
|
||||||
if (index_type->isLong())
|
|
||||||
size = INT_MAX; // should be ULLONG_MAX + 1ULL;
|
|
||||||
else
|
|
||||||
size = INT_MAX; // should be ULONG_MAX + 1UL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (index_type->isLong())
|
|
||||||
size = INT_MAX; // should be LLONG_MAX + 1LL;
|
|
||||||
else
|
|
||||||
size = INT_MAX; // should be LONG_MAX + 1L;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type = tok->strAt(varpos - 1);
|
|
||||||
varid = tok->tokAt(varpos)->varId();
|
|
||||||
nextTok = varpos + 5;
|
|
||||||
}
|
|
||||||
else if (indentlevel > 0 && Token::Match(tok, "[*;{}] %var% = new %type% [ %num% ]"))
|
|
||||||
{
|
{
|
||||||
size = MathLib::toLongNumber(tok->strAt(6));
|
size = MathLib::toLongNumber(tok->strAt(6));
|
||||||
type = tok->strAt(4);
|
type = tok->strAt(4);
|
||||||
|
|
Loading…
Reference in New Issue