Fixed #959 (new check: wrong usage of fflush())

This commit is contained in:
Zachary Blair 2010-05-03 23:14:45 -07:00
parent 804b2a0952
commit 707d27f3d8
3 changed files with 48 additions and 1 deletions

View File

@ -254,6 +254,19 @@ void CheckOther::checkEmptyStringTest()
}
}
}
//---------------------------------------------------------------------------
// fflush(stdin) <- fflush only applies to output streams in ANSI C
//---------------------------------------------------------------------------
void CheckOther::checkFflushOnInputStream()
{
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{
if (Token::Match(tok, "fflush ( stdin )"))
{
fflushOnInputStreamError(tok, tok->strAt(2));
}
}
}
//---------------------------------------------------------------------------
// strtol(str, 0, radix) <- radix must be 0 or 2-36
@ -3502,3 +3515,9 @@ void CheckOther::emptyStringTestError(const Token *tok, const std::string &var_n
"emptyStringTest", "Non-empty string test can be simplified to \"*" + var_name + " != '\\0'\"");
}
}
void CheckOther::fflushOnInputStreamError(const Token *tok, const std::string &varname)
{
reportError(tok, Severity::possibleError,
"fflushOnInputStream", "fflush() called on input stream \"" + varname + "\" may result in undefined behaviour");
}

View File

@ -77,6 +77,7 @@ public:
checkOther.invalidFunctionUsage();
checkOther.checkZeroDivision();
checkOther.checkMathFunctions();
checkOther.checkFflushOnInputStream();
// New type of check: Check execution paths
checkOther.executionPaths();
@ -158,6 +159,9 @@ public:
/** @brief %Check for inefficient empty string test*/
void checkEmptyStringTest();
/** @brief %Check for using fflush() on an input stream*/
void checkFflushOnInputStream();
// Error messages..
void cstyleCastError(const Token *tok);
void redundantIfDelete0Error(const Token *tok);
@ -184,6 +188,7 @@ public:
void mathfunctionCallError(const Token *tok, const unsigned int numParam = 1);
void postIncrementError(const Token *tok, const std::string &var_name, const bool isIncrement);
void emptyStringTestError(const Token *tok, const std::string &var_name, const bool isTestForEmpty);
void fflushOnInputStreamError(const Token *tok, const std::string &varname);
void getErrorMessages()
{
@ -196,6 +201,7 @@ public:
uninitvarError(0, "varname");
zerodivError(0);
mathfunctionCallError(0);
fflushOnInputStreamError(0, "stdin");
// style
cstyleCastError(0);
@ -232,6 +238,9 @@ public:
"* null pointer dereferencing\n"
"* using uninitialized variables and data\n"
// possible error
"* using fflush() on an input stream\n"
// style
"* C-style pointer cast in cpp file\n"
"* redundant if\n"
@ -246,7 +255,8 @@ public:
"* unusal pointer arithmetic. For example: \"abc\" + 'd'\n"
// optimisations
"* optimisation: detect post increment/decrement\n";
"* optimisation: detect post increment/decrement\n"
"* optimisation: simplify empty string tests\n";
}
private:

View File

@ -92,6 +92,8 @@ private:
TEST_CASE(mathfunctionCall1);
TEST_CASE(emptyStringTest);
TEST_CASE(fflushOnInputStreamTest);
}
void check(const char code[])
@ -115,6 +117,7 @@ private:
checkOther.checkZeroDivision();
checkOther.checkMathFunctions();
checkOther.checkEmptyStringTest();
checkOther.checkFflushOnInputStream();
}
@ -2471,6 +2474,21 @@ private:
check("if (0 < strlen(str)) { }");
ASSERT_EQUALS("[test.cpp:1]: (possible style) Non-empty string test can be simplified to \"*str != '\\0'\"\n", errout.str());
}
void fflushOnInputStreamTest()
{
check("void foo()\n"
"{\n"
" fflush(stdin);\n"
"}\n");
ASSERT_EQUALS("[test.cpp:3]: (possible error) fflush() called on input stream \"stdin\" may result in undefined behaviour\n", errout.str());
check("void foo()\n"
"{\n"
" fflush(stdout);\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
};
REGISTER_TEST(TestOther)