diff --git a/lib/checkother.cpp b/lib/checkother.cpp index eaa7752fb..2ff551e57 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -79,24 +79,25 @@ void CheckOther::checkFflushOnInputStream() } -void CheckOther::checkSizeofWithSilentArrayPointer() +void CheckOther::checkSizeofForArrayParameter() { for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { if (Token::Match(tok, "sizeof ( %var% )") || Token::Match(tok, "sizeof %var% ")) { int tokIdx = 1; - if (tok->tokAt(tokIdx)->str() == "(") { + if (tok->tokAt(tokIdx)->str() == "(") + { ++tokIdx; } if (tok->tokAt(tokIdx)->varId() > 0) { - const Token *declTok = Token::findmatch(_tokenizer->tokens(), "%varid% [", tok->tokAt(tokIdx)->varId()); + const Token *declTok = Token::findmatch(_tokenizer->tokens(), "%varid%", tok->tokAt(tokIdx)->varId()); if (declTok) { - if (!(Token::simpleMatch(declTok->next()->link(), "] = {")) && !(Token::simpleMatch(declTok->next()->link(), "] ;"))) + if ((Token::simpleMatch(declTok->next(), "[")) && !(Token::simpleMatch(declTok->next()->link(), "] = {")) && !(Token::simpleMatch(declTok->next()->link(), "] ;"))) { - sizeofWithSilentArrayPointerError(tok); + sizeofForArrayParameterError(tok); } } } @@ -482,10 +483,21 @@ void CheckOther::invalidScanf() } } -void CheckOther::sizeofWithSilentArrayPointerError(const Token *tok) +void CheckOther::sizeofForArrayParameterError(const Token *tok) { - reportError(tok, Severity::error, "sizeofwithsilentarraypointer", "silent pointer of array is passed as parameter to the function sizeof."); - + reportError(tok, Severity::error, + "sizeofwithsilentarraypointer", "Using sizeof for array given as function argument " + "returns the size of pointer.\n" + "Giving array as function parameter and then using sizeof-operator for the array " + "argument. In this case the sizeof-operator returns the size of pointer (in the " + " system). It does not return the size of the whole array in bytes as might be " + "expected. For example, this code:\n" + " int f(char a[100]) {\n" + " return sizeof(a);\n" + " }\n" + " returns 4 (in 32-bit systems) or 8 (in 64-bit systems) instead of 100 (the " + "size of the array in bytes)." + ); } void CheckOther::invalidScanfError(const Token *tok) { diff --git a/lib/checkother.h b/lib/checkother.h index 7e01a034a..0d0798dd7 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -62,7 +62,7 @@ public: checkOther.sizeofCalculation(); checkOther.checkRedundantAssignmentInSwitch(); checkOther.checkAssignmentInAssert(); - checkOther.checkSizeofWithSilentArrayPointer(); + checkOther.checkSizeofForArrayParameter(); } /** @brief Run checks against the simplified token list */ @@ -171,8 +171,8 @@ public: /** @brief %Check for filling zero bytes with memset() */ void checkMemsetZeroBytes(); - /** @brief %Check if parameter of sizeof() is typed as a silent pointer of array */ - void checkSizeofWithSilentArrayPointer(); + /** @brief %Check for using sizeof with array given as function argument */ + void checkSizeofForArrayParameter(); // Error messages.. void cstyleCastError(const Token *tok); @@ -197,7 +197,7 @@ public: void misusedScopeObjectError(const Token *tok, const std::string &varname); void catchExceptionByValueError(const Token *tok); void memsetZeroBytesError(const Token *tok, const std::string &varname); - void sizeofWithSilentArrayPointerError(const Token *tok); + void sizeofForArrayParameterError(const Token *tok); void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) { @@ -210,7 +210,7 @@ public: c.mathfunctionCallError(0); c.fflushOnInputStreamError(0, "stdin"); c.misusedScopeObjectError(NULL, "varname"); - c.sizeofWithSilentArrayPointerError(0); + c.sizeofForArrayParameterError(0); // style/warning c.cstyleCastError(0); @@ -253,7 +253,7 @@ public: "* using fflush() on an input stream\n" "* scoped object destroyed immediately after construction\n" "* assignment in an assert statement\n" - "* silent array pointer as parameter of sizeof\n" + "* sizeof for array given as function argument\n" // style "* C-style pointer cast in cpp file\n" diff --git a/test/testother.cpp b/test/testother.cpp index 19326febb..934ab01ca 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -120,7 +120,7 @@ private: checkOther.sizeofCalculation(); checkOther.checkRedundantAssignmentInSwitch(); checkOther.checkAssignmentInAssert(); - checkOther.checkSizeofWithSilentArrayPointer(); + checkOther.checkSizeofForArrayParameter(); // Simplify token list.. tokenizer.simplifyTokenList(); @@ -1718,19 +1718,29 @@ private: " std::cout << sizeof(a) / sizeof(int) << std::endl;\n" "}\n" ); - ASSERT_EQUALS("[test.cpp:2]: (error) silent pointer of array is passed as parameter to the function sizeof.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (error) Using sizeof for array given as " + "function argument returns the size of pointer.\n", errout.str()); check("void f( int a[]) {\n" " std::cout << sizeof a / sizeof(int) << std::endl;\n" "}\n" ); - ASSERT_EQUALS("[test.cpp:2]: (error) silent pointer of array is passed as parameter to the function sizeof.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (error) Using sizeof for array given as " + "function argument returns the size of pointer.\n", errout.str()); check("void f( int a[3] ) {\n" " std::cout << sizeof(a) / sizeof(int) << std::endl;\n" "}\n" ); - ASSERT_EQUALS("[test.cpp:2]: (error) silent pointer of array is passed as parameter to the function sizeof.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (error) Using sizeof for array given as " + "function argument returns the size of pointer.\n", errout.str()); + + check("void f(int *p) {\n" + " p[0] = 0;\n" + " sizeof(p);\n" + "}\n" + ); + ASSERT_EQUALS("", errout.str()); }