another partial fix for #3063 (false negative: multi dimensional arrays not well supported)

This commit is contained in:
Robert Reif 2011-09-02 21:07:29 -04:00
parent d85410de8c
commit d749e28dc0
4 changed files with 46 additions and 2 deletions

View File

@ -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);
}
}
} }
} }
} }

View File

@ -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;

View File

@ -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()

View File

@ -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"