Fixed #4173: New check: arithmetical usage of inf/nan result
This commit is contained in:
parent
f359bfca9c
commit
28c0045f36
|
@ -2112,6 +2112,30 @@ void CheckOther::zerodivError(const Token *tok)
|
|||
reportError(tok, Severity::error, "zerodiv", "Division by zero.");
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
/** @brief Check for NaN (not-a-number) in an arithmetic expression
|
||||
* @note e.g. double d = 1.0 / 0.0 + 100.0;
|
||||
*/
|
||||
void CheckOther::checkNanInArithmeticExpression()
|
||||
{
|
||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||
if (Token::Match(tok, "inf.0 +|-") ||
|
||||
Token::Match(tok, "+|- inf.0") ||
|
||||
Token::Match(tok, "+|- %num% / 0.0")) {
|
||||
nanInArithmeticExpressionError(tok);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckOther::nanInArithmeticExpressionError(const Token *tok)
|
||||
{
|
||||
reportError(tok, Severity::style, "nanInArithmeticExpression",
|
||||
"Using NaN/Inf in a computation.\n"
|
||||
"Although nothing bad really happens, it is suspicious.");
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------
|
||||
void CheckOther::checkMathFunctions()
|
||||
|
|
|
@ -72,6 +72,7 @@ public:
|
|||
checkOther.checkIncompleteArrayFill();
|
||||
checkOther.checkSuspiciousStringCompare();
|
||||
checkOther.checkVarFuncNullUB();
|
||||
checkOther.checkNanInArithmeticExpression();
|
||||
}
|
||||
|
||||
/** @brief Run checks against the simplified token list */
|
||||
|
@ -158,6 +159,9 @@ public:
|
|||
/** @brief %Check zero division*/
|
||||
void checkZeroDivision();
|
||||
|
||||
/** @brief Check for NaN (not-a-number) in an arithmetic expression */
|
||||
void checkNanInArithmeticExpression();
|
||||
|
||||
/** @brief %Check for parameters given to math function that do not make sense*/
|
||||
void checkMathFunctions();
|
||||
|
||||
|
@ -278,6 +282,7 @@ private:
|
|||
void variableScopeError(const Token *tok, const std::string &varname);
|
||||
void strPlusCharError(const Token *tok);
|
||||
void zerodivError(const Token *tok);
|
||||
void nanInArithmeticExpressionError(const Token *tok);
|
||||
void mathfunctionCallError(const Token *tok, const unsigned int numParam = 1);
|
||||
void cctypefunctionCallError(const Token *tok, const std::string &functionName, const std::string &value);
|
||||
void redundantAssignmentError(const Token *tok1, const Token* tok2, const std::string& var, bool inconclusive);
|
||||
|
@ -377,6 +382,7 @@ private:
|
|||
c.moduloAlwaysTrueFalseError(0, "1");
|
||||
c.incompleteArrayFillError(0, "buffer", "memset", false);
|
||||
c.varFuncNullUBError(0);
|
||||
c.nanInArithmeticExpressionError(0);
|
||||
}
|
||||
|
||||
static std::string myName() {
|
||||
|
@ -438,7 +444,8 @@ private:
|
|||
"* Comparisons of modulo results that are always true/false.\n"
|
||||
"* Array filled incompletely using memset/memcpy/memmove.\n"
|
||||
"* redundant get and set function of user id (--std=posix).\n"
|
||||
"* Passing NULL pointer to function with variable number of arguments leads to UB on some platforms.\n";
|
||||
"* Passing NULL pointer to function with variable number of arguments leads to UB on some platforms.\n"
|
||||
"* NaN (not a number) value used in arithmetic expression.\n";
|
||||
}
|
||||
|
||||
void checkExpressionRange(const std::list<const Function*> &constFunctions,
|
||||
|
|
|
@ -43,6 +43,8 @@ private:
|
|||
TEST_CASE(zeroDiv5);
|
||||
TEST_CASE(zeroDiv6);
|
||||
|
||||
TEST_CASE(nanInArithmeticExpression);
|
||||
|
||||
TEST_CASE(sprintf1); // Dangerous usage of sprintf
|
||||
TEST_CASE(sprintf2);
|
||||
TEST_CASE(sprintf3);
|
||||
|
@ -410,6 +412,47 @@ private:
|
|||
ASSERT_EQUALS("[test.cpp:3]: (error) Division by zero.\n", errout.str());
|
||||
}
|
||||
|
||||
void nanInArithmeticExpression() {
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
" double x = 3.0 / 0.0 + 1.0\n"
|
||||
" printf(\"%f\n\", x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS(
|
||||
"[test.cpp:3]: (style) Using NaN/Inf in a computation.\n", errout.str());
|
||||
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
" double x = 3.0 / 0.0 - 1.0\n"
|
||||
" printf(\"%f\n\", x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS(
|
||||
"[test.cpp:3]: (style) Using NaN/Inf in a computation.\n", errout.str());
|
||||
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
" double x = 1.0 + 3.0 / 0.0\n"
|
||||
" printf(\"%f\n\", x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS(
|
||||
"[test.cpp:3]: (style) Using NaN/Inf in a computation.\n", errout.str());
|
||||
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
" double x = 1.0 - 3.0 / 0.0\n"
|
||||
" printf(\"%f\n\", x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS(
|
||||
"[test.cpp:3]: (style) Using NaN/Inf in a computation.\n", errout.str());
|
||||
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
" double x = 3.0 / 0.0\n"
|
||||
" printf(\"%f\n\", x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
}
|
||||
|
||||
void sprintfUsage(const char code[]) {
|
||||
// Clear the error buffer..
|
||||
|
|
Loading…
Reference in New Issue