Fixed #934 (new check: missuse of std::cout)

This commit is contained in:
PKEuS 2011-10-22 17:12:52 +02:00 committed by Daniel Marjamäki
parent ca95eea1ae
commit 20179673ce
3 changed files with 72 additions and 6 deletions

View File

@ -664,6 +664,29 @@ void CheckOther::switchCaseFallThrough(const Token *tok)
"switchCaseFallThrough", "Switch falls through case without comment");
}
//---------------------------------------------------------------------------
// std::cout << std::cout;
//---------------------------------------------------------------------------
void CheckOther::checkCoutCerrMisusage()
{
bool firstCout = false;
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
if (Token::Match(tok, "std :: cout|cerr")) {
if (firstCout && tok->strAt(-1) == "<<" && tok->strAt(3) != ".") {
coutCerrMisusageError(tok, tok->strAt(2));
firstCout = false;
} else if (tok->strAt(3) == "<<")
firstCout = true;
} else if (firstCout && tok->str() == ";")
firstCout = false;
}
}
void CheckOther::coutCerrMisusageError(const Token* tok, const std::string& streamName)
{
reportError(tok, Severity::error, "coutCerrMisusage", "Invalid usage of output stream: '<< std::" + streamName + "'.");
}
//---------------------------------------------------------------------------
// int x = 1;
// x = x; // <- redundant assignment to self

View File

@ -89,6 +89,7 @@ public:
checkOther.checkFflushOnInputStream();
checkOther.invalidScanf();
checkOther.checkCoutCerrMisusage();
checkOther.checkIncorrectLogicOperator();
checkOther.checkMisusedScopedObject();
checkOther.checkCatchExceptionByValue();
@ -171,6 +172,9 @@ public:
/** @brief %Check for switch case fall through without comment */
void checkSwitchCaseFallThrough();
/** @brief %Check for missusage of std::cout */
void checkCoutCerrMisusage();
/** @brief %Check for assigning a variable to itself*/
void checkSelfAssignment();
@ -246,6 +250,7 @@ public:
void variableScopeError(const Token *tok, const std::string &varname);
void strPlusCharError(const Token *tok);
void zerodivError(const Token *tok);
void coutCerrMisusageError(const Token* tok, const std::string& streamName);
void mathfunctionCallError(const Token *tok, const unsigned int numParam = 1);
void fflushOnInputStreamError(const Token *tok, const std::string &varname);
void redundantAssignmentInSwitchError(const Token *tok, const std::string &varname);
@ -289,6 +294,7 @@ public:
c.misusedScopeObjectError(NULL, "varname");
c.sizeofForArrayParameterError(0);
c.sizeofForNumericParameterError(0);
c.coutCerrMisusageError(0, "cout");
// style/warning
c.cstyleCastError(0);
@ -345,6 +351,7 @@ public:
"* sizeof for array given as function argument\n"
"* sizeof for numeric given as function argument\n"
"* incorrect length arguments for 'substr' and 'strncmp'\n"
"* invalid usage of output stream. For example: std::cout << std::cout;'\n"
// style
"* C-style pointer cast in cpp file\n"

View File

@ -81,6 +81,8 @@ private:
TEST_CASE(switchFallThroughCase);
TEST_CASE(duplicateBreak);
TEST_CASE(coutCerrMisusage);
TEST_CASE(selfAssignment);
TEST_CASE(testScanf1);
TEST_CASE(testScanf2);
@ -180,6 +182,7 @@ private:
checkOther.checkFflushOnInputStream();
checkOther.checkSelfAssignment();
checkOther.invalidScanf();
checkOther.checkCoutCerrMisusage();
checkOther.checkMisusedScopedObject();
checkOther.checkIncorrectLogicOperator();
checkOther.checkCatchExceptionByValue();
@ -1286,15 +1289,15 @@ private:
check("void foo(char *str, int a)\n"
"{\n"
" int z = 0;\n"
" int z = 0;\n"
" switch (a)\n"
" {\n"
" case 2:\n"
" strcpy(str, \"a'\");\n"
" z++;\n"
" z++;\n"
" case 3:\n"
" strcpy(str, \"b'\");\n"
" z++;\n"
" z++;\n"
" }\n"
"}\n");
ASSERT_EQUALS("[test.cpp:7]: (warning) Switch case fall-through. Redundant strcpy of \"str\".\n", errout.str());
@ -1305,10 +1308,10 @@ private:
" {\n"
" case 2:\n"
" strcpy(str, \"a'\");\n"
" break;\n"
" break;\n"
" case 3:\n"
" strcpy(str, \"b'\");\n"
" break;\n"
" break;\n"
" }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
@ -1319,7 +1322,7 @@ private:
" {\n"
" case 2:\n"
" strcpy(str, \"a'\");\n"
" printf(str);\n"
" printf(str);\n"
" case 3:\n"
" strcpy(str, \"b'\");\n"
" }\n"
@ -3747,6 +3750,39 @@ private:
"}");
ASSERT_EQUALS("", errout.str());
}
void coutCerrMisusage() {
check(
"void foo() {\n"
" std::cout << std::cout;\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (error) Invalid usage of output stream: '<< std::cout'.\n", errout.str());
check(
"void foo() {\n"
" std::cout << \"xyz\" << std::cout;\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (error) Invalid usage of output stream: '<< std::cout'.\n", errout.str());
check(
"void foo(int i) {\n"
" std::cout << i << std::cerr;\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (error) Invalid usage of output stream: '<< std::cerr'.\n", errout.str());
check(
"void foo() {\n"
" std::cout << \"xyz\";\n"
" std::cout << \"xyz\";\n"
"}");
ASSERT_EQUALS("", errout.str());
check(
"void foo() {\n"
" std::cout << std::cout.good();\n"
"}");
ASSERT_EQUALS("", errout.str());
}
};
REGISTER_TEST(TestOther)