#5805 'Passing value -1.0 to sqrt() leads to undefined result' is incorrect. Degrade wrongmathcall from error to warning, since it deals with implementation-defined behaviour
This commit is contained in:
parent
80df3dc642
commit
a4ff30301a
|
@ -1894,57 +1894,57 @@ void CheckOther::checkMathFunctions()
|
|||
bool isInt = MathLib::isInt(tok->strAt(2));
|
||||
bool isFloat = MathLib::isFloat(tok->strAt(2));
|
||||
if (isNegative && isInt && MathLib::toLongNumber(tok->strAt(2)) <= 0) {
|
||||
mathfunctionCallError(tok); // case log(-2)
|
||||
mathfunctionCallWarning(tok); // case log(-2)
|
||||
} else if (isNegative && isFloat && MathLib::toDoubleNumber(tok->strAt(2)) <= 0.) {
|
||||
mathfunctionCallError(tok); // case log(-2.0)
|
||||
mathfunctionCallWarning(tok); // case log(-2.0)
|
||||
} else if (!isNegative && isFloat && MathLib::toDoubleNumber(tok->strAt(2)) <= 0.) {
|
||||
mathfunctionCallError(tok); // case log(0.0)
|
||||
mathfunctionCallWarning(tok); // case log(0.0)
|
||||
} else if (!isNegative && isInt && MathLib::toLongNumber(tok->strAt(2)) <= 0) {
|
||||
mathfunctionCallError(tok); // case log(0)
|
||||
mathfunctionCallWarning(tok); // case log(0)
|
||||
}
|
||||
}
|
||||
|
||||
// acos( x ), asin( x ) where x is defined for interval [-1,+1], but not beyond
|
||||
else if (Token::Match(tok, "acos|acosl|acosf|asin|asinf|asinl ( %num% )") &&
|
||||
std::fabs(MathLib::toDoubleNumber(tok->strAt(2))) > 1.0) {
|
||||
mathfunctionCallError(tok);
|
||||
mathfunctionCallWarning(tok);
|
||||
}
|
||||
// sqrt( x ): if x is negative the result is undefined
|
||||
else if (Token::Match(tok, "sqrt|sqrtf|sqrtl ( %num% )") &&
|
||||
MathLib::isNegative(tok->strAt(2))) {
|
||||
mathfunctionCallError(tok);
|
||||
mathfunctionCallWarning(tok);
|
||||
}
|
||||
// atan2 ( x , y): x and y can not be zero, because this is mathematically not defined
|
||||
else if (Token::Match(tok, "atan2|atan2f|atan2l ( %num% , %num% )") &&
|
||||
MathLib::isNullValue(tok->strAt(2)) &&
|
||||
MathLib::isNullValue(tok->strAt(4))) {
|
||||
mathfunctionCallError(tok, 2);
|
||||
mathfunctionCallWarning(tok, 2);
|
||||
}
|
||||
// fmod ( x , y) If y is zero, then either a range error will occur or the function will return zero (implementation-defined).
|
||||
else if (Token::Match(tok, "fmod|fmodf|fmodl ( %any%")) {
|
||||
const Token* nextArg = tok->tokAt(2)->nextArgument();
|
||||
if (nextArg && nextArg->isNumber() && MathLib::isNullValue(nextArg->str()))
|
||||
mathfunctionCallError(tok, 2);
|
||||
mathfunctionCallWarning(tok, 2);
|
||||
}
|
||||
// pow ( x , y) If x is zero, and y is negative --> division by zero
|
||||
else if (Token::Match(tok, "pow|powf|powl ( %num% , %num% )") &&
|
||||
MathLib::isNullValue(tok->strAt(2)) &&
|
||||
MathLib::isNegative(tok->strAt(4))) {
|
||||
mathfunctionCallError(tok, 2);
|
||||
mathfunctionCallWarning(tok, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckOther::mathfunctionCallError(const Token *tok, const unsigned int numParam)
|
||||
void CheckOther::mathfunctionCallWarning(const Token *tok, const unsigned int numParam)
|
||||
{
|
||||
if (tok) {
|
||||
if (numParam == 1)
|
||||
reportError(tok, Severity::error, "wrongmathcall", "Passing value " + tok->strAt(2) + " to " + tok->str() + "() leads to undefined result.");
|
||||
reportError(tok, Severity::warning, "wrongmathcall", "Passing value " + tok->strAt(2) + " to " + tok->str() + "() leads to implementation-defined result.");
|
||||
else if (numParam == 2)
|
||||
reportError(tok, Severity::error, "wrongmathcall", "Passing values " + tok->strAt(2) + " and " + tok->strAt(4) + " to " + tok->str() + "() leads to undefined result.");
|
||||
reportError(tok, Severity::warning, "wrongmathcall", "Passing values " + tok->strAt(2) + " and " + tok->strAt(4) + " to " + tok->str() + "() leads to implementation-defined result.");
|
||||
} else
|
||||
reportError(tok, Severity::error, "wrongmathcall", "Passing value '#' to #() leads to undefined result.");
|
||||
reportError(tok, Severity::warning, "wrongmathcall", "Passing value '#' to #() leads to implementation-defined result.");
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -257,7 +257,7 @@ private:
|
|||
void zerodivError(const Token *tok, bool inconclusive);
|
||||
void zerodivcondError(const Token *tokcond, const Token *tokdiv, bool inconclusive);
|
||||
void nanInArithmeticExpressionError(const Token *tok);
|
||||
void mathfunctionCallError(const Token *tok, const unsigned int numParam = 1);
|
||||
void mathfunctionCallWarning(const Token *tok, const unsigned int numParam = 1);
|
||||
void redundantAssignmentError(const Token *tok1, const Token* tok2, const std::string& var, bool inconclusive);
|
||||
void redundantAssignmentInSwitchError(const Token *tok1, const Token *tok2, const std::string &var);
|
||||
void redundantCopyError(const Token *tok1, const Token* tok2, const std::string& var);
|
||||
|
@ -299,7 +299,6 @@ private:
|
|||
c.udivError(0, false);
|
||||
c.zerodivError(0, false);
|
||||
c.zerodivcondError(0,0,false);
|
||||
c.mathfunctionCallError(0);
|
||||
c.misusedScopeObjectError(NULL, "varname");
|
||||
c.doubleFreeError(0, "varname");
|
||||
c.invalidPointerCastError(0, "float", "double", false);
|
||||
|
@ -326,6 +325,7 @@ private:
|
|||
c.suspiciousCaseInSwitchError(0, "||");
|
||||
c.suspiciousEqualityComparisonError(0);
|
||||
c.selfAssignmentError(0, "varname");
|
||||
c.mathfunctionCallWarning(0);
|
||||
c.memsetZeroBytesError(0, "varname");
|
||||
c.memsetFloatError(0, "varname");
|
||||
c.memsetValueOutOfRangeError(0, "varname");
|
||||
|
|
|
@ -1336,9 +1336,18 @@ private:
|
|||
" std::cout << sqrtf(-1) << std::endl;\n"
|
||||
" std::cout << sqrtl(-1) << std::endl;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Passing value -1 to sqrt() leads to undefined result.\n"
|
||||
"[test.cpp:4]: (error) Passing value -1 to sqrtf() leads to undefined result.\n"
|
||||
"[test.cpp:5]: (error) Passing value -1 to sqrtl() leads to undefined result.\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:3]: (warning) Passing value -1 to sqrt() leads to implementation-defined result.\n"
|
||||
"[test.cpp:4]: (warning) Passing value -1 to sqrtf() leads to implementation-defined result.\n"
|
||||
"[test.cpp:5]: (warning) Passing value -1 to sqrtl() leads to implementation-defined result.\n", errout.str());
|
||||
|
||||
// implementation-defined behaviour for "finite values of x<0" only:
|
||||
check("void foo()\n"
|
||||
"{\n"
|
||||
" std::cout << sqrt(-0.) << std::endl;\n"
|
||||
" std::cout << sqrtf(-0.) << std::endl;\n"
|
||||
" std::cout << sqrtl(-0.) << std::endl;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void foo()\n"
|
||||
"{\n"
|
||||
|
@ -1357,9 +1366,9 @@ private:
|
|||
" std::cout << logf(-2) << std::endl;\n"
|
||||
" std::cout << logl(-2) << std::endl;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Passing value -2 to log() leads to undefined result.\n"
|
||||
"[test.cpp:4]: (error) Passing value -2 to logf() leads to undefined result.\n"
|
||||
"[test.cpp:5]: (error) Passing value -2 to logl() leads to undefined result.\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:3]: (warning) Passing value -2 to log() leads to implementation-defined result.\n"
|
||||
"[test.cpp:4]: (warning) Passing value -2 to logf() leads to implementation-defined result.\n"
|
||||
"[test.cpp:5]: (warning) Passing value -2 to logl() leads to implementation-defined result.\n", errout.str());
|
||||
|
||||
check("void foo()\n"
|
||||
"{\n"
|
||||
|
@ -1367,9 +1376,9 @@ private:
|
|||
" std::cout << logf(-1) << std::endl;\n"
|
||||
" std::cout << logl(-1) << std::endl;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Passing value -1 to log() leads to undefined result.\n"
|
||||
"[test.cpp:4]: (error) Passing value -1 to logf() leads to undefined result.\n"
|
||||
"[test.cpp:5]: (error) Passing value -1 to logl() leads to undefined result.\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:3]: (warning) Passing value -1 to log() leads to implementation-defined result.\n"
|
||||
"[test.cpp:4]: (warning) Passing value -1 to logf() leads to implementation-defined result.\n"
|
||||
"[test.cpp:5]: (warning) Passing value -1 to logl() leads to implementation-defined result.\n", errout.str());
|
||||
|
||||
check("void foo()\n"
|
||||
"{\n"
|
||||
|
@ -1377,9 +1386,9 @@ private:
|
|||
" std::cout << logf(-1.0) << std::endl;\n"
|
||||
" std::cout << logl(-1.0) << std::endl;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Passing value -1.0 to log() leads to undefined result.\n"
|
||||
"[test.cpp:4]: (error) Passing value -1.0 to logf() leads to undefined result.\n"
|
||||
"[test.cpp:5]: (error) Passing value -1.0 to logl() leads to undefined result.\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:3]: (warning) Passing value -1.0 to log() leads to implementation-defined result.\n"
|
||||
"[test.cpp:4]: (warning) Passing value -1.0 to logf() leads to implementation-defined result.\n"
|
||||
"[test.cpp:5]: (warning) Passing value -1.0 to logl() leads to implementation-defined result.\n", errout.str());
|
||||
|
||||
check("void foo()\n"
|
||||
"{\n"
|
||||
|
@ -1387,9 +1396,9 @@ private:
|
|||
" std::cout << logf(-0.1) << std::endl;\n"
|
||||
" std::cout << logl(-0.1) << std::endl;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Passing value -0.1 to log() leads to undefined result.\n"
|
||||
"[test.cpp:4]: (error) Passing value -0.1 to logf() leads to undefined result.\n"
|
||||
"[test.cpp:5]: (error) Passing value -0.1 to logl() leads to undefined result.\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:3]: (warning) Passing value -0.1 to log() leads to implementation-defined result.\n"
|
||||
"[test.cpp:4]: (warning) Passing value -0.1 to logf() leads to implementation-defined result.\n"
|
||||
"[test.cpp:5]: (warning) Passing value -0.1 to logl() leads to implementation-defined result.\n", errout.str());
|
||||
|
||||
check("void foo()\n"
|
||||
"{\n"
|
||||
|
@ -1397,9 +1406,9 @@ private:
|
|||
" std::cout << logf(0.) << std::endl;\n"
|
||||
" std::cout << logl(0.0) << std::endl;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Passing value 0 to log() leads to undefined result.\n"
|
||||
"[test.cpp:4]: (error) Passing value 0. to logf() leads to undefined result.\n"
|
||||
"[test.cpp:5]: (error) Passing value 0.0 to logl() leads to undefined result.\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:3]: (warning) Passing value 0 to log() leads to implementation-defined result.\n"
|
||||
"[test.cpp:4]: (warning) Passing value 0. to logf() leads to implementation-defined result.\n"
|
||||
"[test.cpp:5]: (warning) Passing value 0.0 to logl() leads to implementation-defined result.\n", errout.str());
|
||||
|
||||
check("void foo()\n"
|
||||
"{\n"
|
||||
|
@ -1476,9 +1485,9 @@ private:
|
|||
" std::cout << acosf(1.1) << std::endl;\n"
|
||||
" std::cout << acosl(1.1) << std::endl;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Passing value 1.1 to acos() leads to undefined result.\n"
|
||||
"[test.cpp:4]: (error) Passing value 1.1 to acosf() leads to undefined result.\n"
|
||||
"[test.cpp:5]: (error) Passing value 1.1 to acosl() leads to undefined result.\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:3]: (warning) Passing value 1.1 to acos() leads to implementation-defined result.\n"
|
||||
"[test.cpp:4]: (warning) Passing value 1.1 to acosf() leads to implementation-defined result.\n"
|
||||
"[test.cpp:5]: (warning) Passing value 1.1 to acosl() leads to implementation-defined result.\n", errout.str());
|
||||
|
||||
check("void foo()\n"
|
||||
"{\n"
|
||||
|
@ -1486,9 +1495,9 @@ private:
|
|||
" std::cout << acosf(-1.1) << std::endl;\n"
|
||||
" std::cout << acosl(-1.1) << std::endl;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Passing value -1.1 to acos() leads to undefined result.\n"
|
||||
"[test.cpp:4]: (error) Passing value -1.1 to acosf() leads to undefined result.\n"
|
||||
"[test.cpp:5]: (error) Passing value -1.1 to acosl() leads to undefined result.\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:3]: (warning) Passing value -1.1 to acos() leads to implementation-defined result.\n"
|
||||
"[test.cpp:4]: (warning) Passing value -1.1 to acosf() leads to implementation-defined result.\n"
|
||||
"[test.cpp:5]: (warning) Passing value -1.1 to acosl() leads to implementation-defined result.\n", errout.str());
|
||||
}
|
||||
|
||||
void mathfunctionCall_asin() {
|
||||
|
@ -1537,9 +1546,9 @@ private:
|
|||
" std::cout << asinf(1.1) << std::endl;\n"
|
||||
" std::cout << asinl(1.1) << std::endl;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Passing value 1.1 to asin() leads to undefined result.\n"
|
||||
"[test.cpp:4]: (error) Passing value 1.1 to asinf() leads to undefined result.\n"
|
||||
"[test.cpp:5]: (error) Passing value 1.1 to asinl() leads to undefined result.\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:3]: (warning) Passing value 1.1 to asin() leads to implementation-defined result.\n"
|
||||
"[test.cpp:4]: (warning) Passing value 1.1 to asinf() leads to implementation-defined result.\n"
|
||||
"[test.cpp:5]: (warning) Passing value 1.1 to asinl() leads to implementation-defined result.\n", errout.str());
|
||||
|
||||
check("void foo()\n"
|
||||
"{\n"
|
||||
|
@ -1547,9 +1556,9 @@ private:
|
|||
" std::cout << asinf(-1.1) << std::endl;\n"
|
||||
" std::cout << asinl(-1.1) << std::endl;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Passing value -1.1 to asin() leads to undefined result.\n"
|
||||
"[test.cpp:4]: (error) Passing value -1.1 to asinf() leads to undefined result.\n"
|
||||
"[test.cpp:5]: (error) Passing value -1.1 to asinl() leads to undefined result.\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:3]: (warning) Passing value -1.1 to asin() leads to implementation-defined result.\n"
|
||||
"[test.cpp:4]: (warning) Passing value -1.1 to asinf() leads to implementation-defined result.\n"
|
||||
"[test.cpp:5]: (warning) Passing value -1.1 to asinl() leads to implementation-defined result.\n", errout.str());
|
||||
}
|
||||
|
||||
void mathfunctionCall_pow() {
|
||||
|
@ -1560,9 +1569,9 @@ private:
|
|||
" std::cout << powf(0,-10) << std::endl;\n"
|
||||
" std::cout << powl(0,-10) << std::endl;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Passing values 0 and -10 to pow() leads to undefined result.\n"
|
||||
"[test.cpp:4]: (error) Passing values 0 and -10 to powf() leads to undefined result.\n"
|
||||
"[test.cpp:5]: (error) Passing values 0 and -10 to powl() leads to undefined result.\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:3]: (warning) Passing values 0 and -10 to pow() leads to implementation-defined result.\n"
|
||||
"[test.cpp:4]: (warning) Passing values 0 and -10 to powf() leads to implementation-defined result.\n"
|
||||
"[test.cpp:5]: (warning) Passing values 0 and -10 to powl() leads to implementation-defined result.\n", errout.str());
|
||||
|
||||
check("void foo()\n"
|
||||
"{\n"
|
||||
|
@ -1619,9 +1628,9 @@ private:
|
|||
" std::cout << atan2f(0,0) << std::endl;\n"
|
||||
" std::cout << atan2l(0,0) << std::endl;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Passing values 0 and 0 to atan2() leads to undefined result.\n"
|
||||
"[test.cpp:4]: (error) Passing values 0 and 0 to atan2f() leads to undefined result.\n"
|
||||
"[test.cpp:5]: (error) Passing values 0 and 0 to atan2l() leads to undefined result.\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:3]: (warning) Passing values 0 and 0 to atan2() leads to implementation-defined result.\n"
|
||||
"[test.cpp:4]: (warning) Passing values 0 and 0 to atan2f() leads to implementation-defined result.\n"
|
||||
"[test.cpp:5]: (warning) Passing values 0 and 0 to atan2l() leads to implementation-defined result.\n", errout.str());
|
||||
}
|
||||
|
||||
void mathfunctionCall_fmod() {
|
||||
|
@ -1632,9 +1641,9 @@ private:
|
|||
" std::cout << fmodf(1.0,0) << std::endl;\n"
|
||||
" std::cout << fmodl(1.0,0) << std::endl;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Passing values 1.0 and 0 to fmod() leads to undefined result.\n"
|
||||
"[test.cpp:4]: (error) Passing values 1.0 and 0 to fmodf() leads to undefined result.\n"
|
||||
"[test.cpp:5]: (error) Passing values 1.0 and 0 to fmodl() leads to undefined result.\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:3]: (warning) Passing values 1.0 and 0 to fmod() leads to implementation-defined result.\n"
|
||||
"[test.cpp:4]: (warning) Passing values 1.0 and 0 to fmodf() leads to implementation-defined result.\n"
|
||||
"[test.cpp:5]: (warning) Passing values 1.0 and 0 to fmodl() leads to implementation-defined result.\n", errout.str());
|
||||
|
||||
check("void foo()\n"
|
||||
"{\n"
|
||||
|
|
Loading…
Reference in New Issue