charvar: dont write warning about char type array index when array is small and the full valid range is accessible with the char type. If there are out of bounds access then, it is not because the type of the variable.

This commit is contained in:
Daniel Marjamäki 2012-03-10 12:19:28 +01:00
parent 81e4eb6503
commit 3f1ab5af9b
2 changed files with 39 additions and 9 deletions

View File

@ -2032,8 +2032,10 @@ void CheckOther::checkCharVariable()
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
if ((tok->str() != ".") && Token::Match(tok->next(), "%var% [ %var% ]")) {
const Variable* var = symbolDatabase->getVariableFromVarId(tok->tokAt(3)->varId());
if (isSignedChar(var))
const Variable* arrayvar = symbolDatabase->getVariableFromVarId(tok->next()->varId());
const Variable* indexvar = symbolDatabase->getVariableFromVarId(tok->tokAt(3)->varId());
const MathLib::bigint arraysize = (arrayvar && arrayvar->isArray()) ? arrayvar->dimension(0U) : 0;
if (isSignedChar(indexvar) && arraysize > 0x80)
charArrayIndexError(tok->next());
}

View File

@ -35,6 +35,7 @@ private:
void run() {
TEST_CASE(array_index_1);
TEST_CASE(array_index_2);
TEST_CASE(array_index_3);
TEST_CASE(bitop1);
TEST_CASE(bitop2);
TEST_CASE(bitop3);
@ -62,32 +63,36 @@ private:
}
void array_index_1() {
check("void foo()\n"
check("int buf[256];\n"
"void foo()\n"
"{\n"
" unsigned char ch = 0x80;\n"
" buf[ch] = 0;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("void foo()\n"
check("int buf[256];\n"
"void foo()\n"
"{\n"
" char ch = 0x80;\n"
" buf[ch] = 0;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (warning) Using char type as array index\n", errout.str());
ASSERT_EQUALS("[test.cpp:5]: (warning) Using char type as array index\n", errout.str());
check("void foo()\n"
check("int buf[256];\n"
"void foo()\n"
"{\n"
" signed char ch = 0x80;\n"
" buf[ch] = 0;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (warning) Using char type as array index\n", errout.str());
ASSERT_EQUALS("[test.cpp:5]: (warning) Using char type as array index\n", errout.str());
check("void foo(char ch)\n"
check("int buf[256];\n"
"void foo(char ch)\n"
"{\n"
" buf[ch] = 0;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:3]: (warning) Using char type as array index\n", errout.str());
ASSERT_EQUALS("[test.cpp:4]: (warning) Using char type as array index\n", errout.str());
check("void foo(const char str[])\n"
"{\n"
@ -106,6 +111,29 @@ private:
ASSERT_EQUALS("", errout.str());
}
void array_index_3() {
// only write error message when array is more than
// 0x80 elements in size. Otherwise the full valid
// range is accessible with a char.
check("char buf[0x81];\n"
"void bar(char c) {\n"
" buf[c] = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (warning) Using char type as array index\n", errout.str());
check("char buf[0x80];\n"
"void bar(char c) {\n"
" buf[c] = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
check("void bar(char c) {\n"
" buf[c] = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void bitop1() {
check("void foo()\n"
"{\n"