diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index d396927a2..c4793ca1e 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -662,8 +662,15 @@ void CheckBufferOverrun::checkFunctionParameter(const Token &tok, unsigned int p } else if (ftok2->str() == ")") break; - else if (parameter == par && Token::Match(ftok2, "%var% ,|)")) - parameterVarId = ftok2->varId(); + else if (parameter == par && Token::Match(ftok2, "%var% ,|)|[")) + { + // check type.. + const Token *type = ftok2->previous(); + while (Token::Match(type, "*|const")) + type = type->previous(); + if (type && _tokenizer->sizeOfType(type) == arrayInfo.element_size()) + parameterVarId = ftok2->varId(); + } } // No parameterVarId => bail out diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 438198b3a..827ceee38 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -118,6 +118,7 @@ private: TEST_CASE(array_index_for_neq); // #2211: Using != in condition TEST_CASE(array_index_for_question); // #2561: for, ?: TEST_CASE(array_index_extern); // FP when using 'extern'. #1684 + TEST_CASE(array_index_cast); // FP after cast. #2841 TEST_CASE(buffer_overrun_1); TEST_CASE(buffer_overrun_2); @@ -1390,6 +1391,31 @@ private: ASSERT_EQUALS("", errout.str()); } + void array_index_cast() + { + // Ticket #2841. FP when using cast. + + // Different types => no error + check("void f1(char *buf) {\n" + " buf[4] = 0;\n" + "}\n" + "void f2() {\n" + " int x[2];\n" + " f1(x);\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + // Same type => error + check("void f1(const char buf[]) {\n" + " char c = buf[4];\n" + "}\n" + "void f2() {\n" + " char x[2];\n" + " f1(x);\n" + "}"); + ASSERT_EQUALS("[test.cpp:6] -> [test.cpp:2]: (error) Array 'x[2]' index 4 out of bounds\n", errout.str()); + } + void buffer_overrun_1() { check("void f()\n"