ticket 155

This commit is contained in:
Sébastien Debrard 2011-01-21 20:16:37 +01:00
parent 211074270c
commit 5842a6a403
3 changed files with 83 additions and 4 deletions

View File

@ -90,11 +90,24 @@ void CheckOther::checkSizeofWithSilentArrayPointer()
const Token *declTok = Token::findmatch(_tokenizer->tokens(), "%varid% [", tok->tokAt(2)->varId()); const Token *declTok = Token::findmatch(_tokenizer->tokens(), "%varid% [", tok->tokAt(2)->varId());
if (declTok) if (declTok)
{ {
unsigned int idx = 2; int idx = 2;
while(!Token::simpleMatch(declTok->tokAt(idx), "]")) { bool bracket = false;
while (!Token::simpleMatch(declTok->tokAt(idx), "]") || bracket)
{
if (Token::simpleMatch(declTok->tokAt(idx), "["))
{
bracket = true;
}
else
{
if (Token::simpleMatch(declTok->tokAt(idx), "]"))
{
bracket = false;
}
}
++idx; ++idx;
} }
if (!(Token::simpleMatch(decltok->tokAt(idx), "] = {")) && !(Token::simpleMatch(decltok->tokAt(idx), "] ;"))) if (!(Token::simpleMatch(declTok->tokAt(idx), "] = {")) && !(Token::simpleMatch(declTok->tokAt(idx), "] ;")))
{ {
sizeofWithSilentArrayPointerError(tok); sizeofWithSilentArrayPointerError(tok);
} }
@ -484,7 +497,7 @@ void CheckOther::invalidScanf()
void CheckOther::sizeofWithSilentArrayPointerError(const Token *tok) void CheckOther::sizeofWithSilentArrayPointerError(const Token *tok)
{ {
reportError(tok, Severity::warning, "sizeofwithsilentarraypointer", "silent pointer of array is passed as parameter to the function sizeof."); reportError(tok, Severity::error, "sizeofwithsilentarraypointer", "silent pointer of array is passed as parameter to the function sizeof.");
} }
void CheckOther::invalidScanfError(const Token *tok) void CheckOther::invalidScanfError(const Token *tok)

View File

@ -62,6 +62,7 @@ public:
checkOther.sizeofCalculation(); checkOther.sizeofCalculation();
checkOther.checkRedundantAssignmentInSwitch(); checkOther.checkRedundantAssignmentInSwitch();
checkOther.checkAssignmentInAssert(); checkOther.checkAssignmentInAssert();
checkOther.checkSizeofWithSilentArrayPointer();
} }
/** @brief Run checks against the simplified token list */ /** @brief Run checks against the simplified token list */
@ -170,6 +171,9 @@ public:
/** @brief %Check for filling zero bytes with memset() */ /** @brief %Check for filling zero bytes with memset() */
void checkMemsetZeroBytes(); void checkMemsetZeroBytes();
/** @brief %Check if parameter of sizeof() is typed as a silent pointer of array */
void checkSizeofWithSilentArrayPointer();
// Error messages.. // Error messages..
void cstyleCastError(const Token *tok); void cstyleCastError(const Token *tok);
void dangerousUsageStrtolError(const Token *tok); void dangerousUsageStrtolError(const Token *tok);
@ -193,6 +197,7 @@ public:
void misusedScopeObjectError(const Token *tok, const std::string &varname); void misusedScopeObjectError(const Token *tok, const std::string &varname);
void catchExceptionByValueError(const Token *tok); void catchExceptionByValueError(const Token *tok);
void memsetZeroBytesError(const Token *tok, const std::string &varname); void memsetZeroBytesError(const Token *tok, const std::string &varname);
void sizeofWithSilentArrayPointerError(const Token *tok);
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings)
{ {
@ -205,6 +210,7 @@ public:
c.mathfunctionCallError(0); c.mathfunctionCallError(0);
c.fflushOnInputStreamError(0, "stdin"); c.fflushOnInputStreamError(0, "stdin");
c.misusedScopeObjectError(NULL, "varname"); c.misusedScopeObjectError(NULL, "varname");
c.sizeofWithSilentArrayPointerError(0);
// style/warning // style/warning
c.cstyleCastError(0); c.cstyleCastError(0);
@ -247,6 +253,7 @@ public:
"* using fflush() on an input stream\n" "* using fflush() on an input stream\n"
"* scoped object destroyed immediately after construction\n" "* scoped object destroyed immediately after construction\n"
"* assignment in an assert statement\n" "* assignment in an assert statement\n"
"* silent array pointer as parameter of sizeof\n"
// style // style
"* C-style pointer cast in cpp file\n" "* C-style pointer cast in cpp file\n"

View File

@ -97,6 +97,8 @@ private:
TEST_CASE(catchExceptionByValue); TEST_CASE(catchExceptionByValue);
TEST_CASE(memsetZeroBytes); TEST_CASE(memsetZeroBytes);
TEST_CASE(sizeofWithSilentArrayPointer);
} }
void check(const char code[], const char *filename = NULL) void check(const char code[], const char *filename = NULL)
@ -118,6 +120,7 @@ private:
checkOther.sizeofCalculation(); checkOther.sizeofCalculation();
checkOther.checkRedundantAssignmentInSwitch(); checkOther.checkRedundantAssignmentInSwitch();
checkOther.checkAssignmentInAssert(); checkOther.checkAssignmentInAssert();
checkOther.checkSizeofWithSilentArrayPointer();
// Simplify token list.. // Simplify token list..
tokenizer.simplifyTokenList(); tokenizer.simplifyTokenList();
@ -1659,6 +1662,62 @@ private:
" bytes of \"p\". Second and third arguments might be inverted.\n", errout.str()); " bytes of \"p\". Second and third arguments might be inverted.\n", errout.str());
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void sizeofWithSilentArrayPointer()
{
check("void f() {\n"
" int a[10];\n"
" std::cout << sizeof(a) / sizeof(int) << std::endl;\n"
"}\n"
);
ASSERT_EQUALS("", errout.str());
check("void f() {\n"
" unsigned int a = 2;\n"
" unsigned int b = 2;\n"
" int c[(a+b)];\n"
" std::cout << sizeof(c) / sizeof(int) << std::endl;\n"
"}\n"
);
ASSERT_EQUALS("", errout.str());
check("void f() {\n"
" unsigned int a[] = { 1 };\n"
" unsigned int b = 2;\n"
" int c[(a[0]+b)];\n"
" std::cout << sizeof(c) / sizeof(int) << std::endl;\n"
"}\n"
);
ASSERT_EQUALS("", errout.str());
check("void f() {\n"
" int a[] = { 1, 2, 3 };\n"
" std::cout << sizeof(a) / sizeof(int) << std::endl;\n"
"}\n"
);
ASSERT_EQUALS("", errout.str());
check("void f() {\n"
" int a[3] = { 1, 2, 3 };\n"
" std::cout << sizeof(a) / sizeof(int) << std::endl;\n"
"}\n"
);
ASSERT_EQUALS("", 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());
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());
}
}; };
REGISTER_TEST(TestOther) REGISTER_TEST(TestOther)