diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 9a8bd4a64..61c750c83 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -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()); } diff --git a/test/testcharvar.cpp b/test/testcharvar.cpp index b2cc85b0b..245a475c4 100644 --- a/test/testcharvar.cpp +++ b/test/testcharvar.cpp @@ -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"