Fixed #934 (new check: missuse of std::cout)
This commit is contained in:
parent
ca95eea1ae
commit
20179673ce
|
@ -664,6 +664,29 @@ void CheckOther::switchCaseFallThrough(const Token *tok)
|
||||||
"switchCaseFallThrough", "Switch falls through case without comment");
|
"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;
|
// int x = 1;
|
||||||
// x = x; // <- redundant assignment to self
|
// x = x; // <- redundant assignment to self
|
||||||
|
|
|
@ -89,6 +89,7 @@ public:
|
||||||
checkOther.checkFflushOnInputStream();
|
checkOther.checkFflushOnInputStream();
|
||||||
checkOther.invalidScanf();
|
checkOther.invalidScanf();
|
||||||
|
|
||||||
|
checkOther.checkCoutCerrMisusage();
|
||||||
checkOther.checkIncorrectLogicOperator();
|
checkOther.checkIncorrectLogicOperator();
|
||||||
checkOther.checkMisusedScopedObject();
|
checkOther.checkMisusedScopedObject();
|
||||||
checkOther.checkCatchExceptionByValue();
|
checkOther.checkCatchExceptionByValue();
|
||||||
|
@ -171,6 +172,9 @@ public:
|
||||||
/** @brief %Check for switch case fall through without comment */
|
/** @brief %Check for switch case fall through without comment */
|
||||||
void checkSwitchCaseFallThrough();
|
void checkSwitchCaseFallThrough();
|
||||||
|
|
||||||
|
/** @brief %Check for missusage of std::cout */
|
||||||
|
void checkCoutCerrMisusage();
|
||||||
|
|
||||||
/** @brief %Check for assigning a variable to itself*/
|
/** @brief %Check for assigning a variable to itself*/
|
||||||
void checkSelfAssignment();
|
void checkSelfAssignment();
|
||||||
|
|
||||||
|
@ -246,6 +250,7 @@ public:
|
||||||
void variableScopeError(const Token *tok, const std::string &varname);
|
void variableScopeError(const Token *tok, const std::string &varname);
|
||||||
void strPlusCharError(const Token *tok);
|
void strPlusCharError(const Token *tok);
|
||||||
void zerodivError(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 mathfunctionCallError(const Token *tok, const unsigned int numParam = 1);
|
||||||
void fflushOnInputStreamError(const Token *tok, const std::string &varname);
|
void fflushOnInputStreamError(const Token *tok, const std::string &varname);
|
||||||
void redundantAssignmentInSwitchError(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.misusedScopeObjectError(NULL, "varname");
|
||||||
c.sizeofForArrayParameterError(0);
|
c.sizeofForArrayParameterError(0);
|
||||||
c.sizeofForNumericParameterError(0);
|
c.sizeofForNumericParameterError(0);
|
||||||
|
c.coutCerrMisusageError(0, "cout");
|
||||||
|
|
||||||
// style/warning
|
// style/warning
|
||||||
c.cstyleCastError(0);
|
c.cstyleCastError(0);
|
||||||
|
@ -345,6 +351,7 @@ public:
|
||||||
"* sizeof for array given as function argument\n"
|
"* sizeof for array given as function argument\n"
|
||||||
"* sizeof for numeric given as function argument\n"
|
"* sizeof for numeric given as function argument\n"
|
||||||
"* incorrect length arguments for 'substr' and 'strncmp'\n"
|
"* incorrect length arguments for 'substr' and 'strncmp'\n"
|
||||||
|
"* invalid usage of output stream. For example: std::cout << std::cout;'\n"
|
||||||
|
|
||||||
// style
|
// style
|
||||||
"* C-style pointer cast in cpp file\n"
|
"* C-style pointer cast in cpp file\n"
|
||||||
|
|
|
@ -81,6 +81,8 @@ private:
|
||||||
TEST_CASE(switchFallThroughCase);
|
TEST_CASE(switchFallThroughCase);
|
||||||
TEST_CASE(duplicateBreak);
|
TEST_CASE(duplicateBreak);
|
||||||
|
|
||||||
|
TEST_CASE(coutCerrMisusage);
|
||||||
|
|
||||||
TEST_CASE(selfAssignment);
|
TEST_CASE(selfAssignment);
|
||||||
TEST_CASE(testScanf1);
|
TEST_CASE(testScanf1);
|
||||||
TEST_CASE(testScanf2);
|
TEST_CASE(testScanf2);
|
||||||
|
@ -180,6 +182,7 @@ private:
|
||||||
checkOther.checkFflushOnInputStream();
|
checkOther.checkFflushOnInputStream();
|
||||||
checkOther.checkSelfAssignment();
|
checkOther.checkSelfAssignment();
|
||||||
checkOther.invalidScanf();
|
checkOther.invalidScanf();
|
||||||
|
checkOther.checkCoutCerrMisusage();
|
||||||
checkOther.checkMisusedScopedObject();
|
checkOther.checkMisusedScopedObject();
|
||||||
checkOther.checkIncorrectLogicOperator();
|
checkOther.checkIncorrectLogicOperator();
|
||||||
checkOther.checkCatchExceptionByValue();
|
checkOther.checkCatchExceptionByValue();
|
||||||
|
@ -1286,15 +1289,15 @@ private:
|
||||||
|
|
||||||
check("void foo(char *str, int a)\n"
|
check("void foo(char *str, int a)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" int z = 0;\n"
|
" int z = 0;\n"
|
||||||
" switch (a)\n"
|
" switch (a)\n"
|
||||||
" {\n"
|
" {\n"
|
||||||
" case 2:\n"
|
" case 2:\n"
|
||||||
" strcpy(str, \"a'\");\n"
|
" strcpy(str, \"a'\");\n"
|
||||||
" z++;\n"
|
" z++;\n"
|
||||||
" case 3:\n"
|
" case 3:\n"
|
||||||
" strcpy(str, \"b'\");\n"
|
" strcpy(str, \"b'\");\n"
|
||||||
" z++;\n"
|
" z++;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:7]: (warning) Switch case fall-through. Redundant strcpy of \"str\".\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:7]: (warning) Switch case fall-through. Redundant strcpy of \"str\".\n", errout.str());
|
||||||
|
@ -1305,10 +1308,10 @@ private:
|
||||||
" {\n"
|
" {\n"
|
||||||
" case 2:\n"
|
" case 2:\n"
|
||||||
" strcpy(str, \"a'\");\n"
|
" strcpy(str, \"a'\");\n"
|
||||||
" break;\n"
|
" break;\n"
|
||||||
" case 3:\n"
|
" case 3:\n"
|
||||||
" strcpy(str, \"b'\");\n"
|
" strcpy(str, \"b'\");\n"
|
||||||
" break;\n"
|
" break;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
@ -1319,7 +1322,7 @@ private:
|
||||||
" {\n"
|
" {\n"
|
||||||
" case 2:\n"
|
" case 2:\n"
|
||||||
" strcpy(str, \"a'\");\n"
|
" strcpy(str, \"a'\");\n"
|
||||||
" printf(str);\n"
|
" printf(str);\n"
|
||||||
" case 3:\n"
|
" case 3:\n"
|
||||||
" strcpy(str, \"b'\");\n"
|
" strcpy(str, \"b'\");\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
|
@ -3747,6 +3750,39 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
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)
|
REGISTER_TEST(TestOther)
|
||||||
|
|
Loading…
Reference in New Issue