another partial fix for #3063 (false negative: multi dimensional arrays not well supported)
This commit is contained in:
parent
d85410de8c
commit
d749e28dc0
|
@ -1931,6 +1931,19 @@ void CheckBufferOverrun::negativeIndex()
|
||||||
const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(tok2->previous()->varId());
|
const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(tok2->previous()->varId());
|
||||||
if (var && var->isArray())
|
if (var && var->isArray())
|
||||||
negativeIndexError(tok, index);
|
negativeIndexError(tok, index);
|
||||||
|
|
||||||
|
// check if this variable is a member of a class/struct
|
||||||
|
else if (!var && Token::Match(tok2->tokAt(-3), "%var% ."))
|
||||||
|
{
|
||||||
|
var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(tok2->tokAt(-3)->varId());
|
||||||
|
if (var && var->type())
|
||||||
|
{
|
||||||
|
// get the variable type from the class/struct
|
||||||
|
const Variable *var2 = var->type()->getVariable(tok2->previous()->str());
|
||||||
|
if (var2 && var2->isArray())
|
||||||
|
negativeIndexError(tok, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1784,6 +1784,19 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess)
|
||||||
return tok;
|
return tok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Variable *Scope::getVariable(const std::string &varname) const
|
||||||
|
{
|
||||||
|
std::list<Variable>::const_iterator iter;
|
||||||
|
|
||||||
|
for (iter = varlist.begin(); iter != varlist.end(); ++iter)
|
||||||
|
{
|
||||||
|
if (iter->name() == varname)
|
||||||
|
return &*iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
const Token* skipScopeIdentifiers(const Token* tok)
|
const Token* skipScopeIdentifiers(const Token* tok)
|
||||||
{
|
{
|
||||||
const Token* ret = tok;
|
const Token* ret = tok;
|
||||||
|
|
|
@ -521,6 +521,13 @@ public:
|
||||||
*/
|
*/
|
||||||
const Token *checkVariable(const Token *tok, AccessControl varaccess);
|
const Token *checkVariable(const Token *tok, AccessControl varaccess);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief get variable from name
|
||||||
|
* @param varname name of variable
|
||||||
|
* @return pointer to variable
|
||||||
|
*/
|
||||||
|
const Variable *getVariable(const std::string &varname) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* @brief helper function for getVariableList()
|
* @brief helper function for getVariableList()
|
||||||
|
|
|
@ -114,7 +114,8 @@ private:
|
||||||
TEST_CASE(array_index_switch_in_for);
|
TEST_CASE(array_index_switch_in_for);
|
||||||
TEST_CASE(array_index_for_in_for); // FP: #2634
|
TEST_CASE(array_index_for_in_for); // FP: #2634
|
||||||
TEST_CASE(array_index_calculation);
|
TEST_CASE(array_index_calculation);
|
||||||
TEST_CASE(array_index_negative);
|
TEST_CASE(array_index_negative1);
|
||||||
|
TEST_CASE(array_index_negative2); // ticket #3063
|
||||||
TEST_CASE(array_index_for_decr);
|
TEST_CASE(array_index_for_decr);
|
||||||
TEST_CASE(array_index_varnames); // FP: struct member. #1576
|
TEST_CASE(array_index_varnames); // FP: struct member. #1576
|
||||||
TEST_CASE(array_index_for_break); // FP: for,break
|
TEST_CASE(array_index_for_break); // FP: for,break
|
||||||
|
@ -1278,7 +1279,7 @@ private:
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Array 'arr[5]' index 11 out of bounds\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:5]: (error) Array 'arr[5]' index 11 out of bounds\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void array_index_negative()
|
void array_index_negative1()
|
||||||
{
|
{
|
||||||
// #948 - array index out of bound not detected 'a[-1] = 0'
|
// #948 - array index out of bound not detected 'a[-1] = 0'
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
|
@ -1318,6 +1319,16 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void array_index_negative2() // ticket #3063
|
||||||
|
{
|
||||||
|
check("struct TEST { char a[10]; };\n"
|
||||||
|
"void foo() {\n"
|
||||||
|
" TEST test;\n"
|
||||||
|
" test.a[-1] = 3;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:4]: (error) Array index -1 is out of bounds\n", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void array_index_for_decr()
|
void array_index_for_decr()
|
||||||
{
|
{
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
|
|
Loading…
Reference in New Issue