Add checks of log2 and log1p range (#1324)
* Add tests for log10{,f,l} valid arguments * Add log2{,f,l} to checkfunctions * Add log1p{,f,l} to checkfunctions * checkfunctions: Simplify check for log function limit out of range The conditions for negative and non-negative int and float were identical so the call to isNegative can be removed and the if-statements be simplified.
This commit is contained in:
parent
c9b91c24dc
commit
710d7ce015
|
@ -226,20 +226,17 @@ void CheckFunctions::checkMathFunctions()
|
||||||
continue;
|
continue;
|
||||||
if (printWarnings && Token::Match(tok, "%name% ( !!)")) {
|
if (printWarnings && Token::Match(tok, "%name% ( !!)")) {
|
||||||
if (tok->strAt(-1) != "."
|
if (tok->strAt(-1) != "."
|
||||||
&& Token::Match(tok, "log|logf|logl|log10|log10f|log10l ( %num% )")) {
|
&& Token::Match(tok, "log|logf|logl|log10|log10f|log10l|log2|log2f|log2l ( %num% )")) {
|
||||||
const std::string& number = tok->strAt(2);
|
const std::string& number = tok->strAt(2);
|
||||||
const bool isNegative = MathLib::isNegative(number);
|
if ((MathLib::isInt(number) && MathLib::toLongNumber(number) <= 0) ||
|
||||||
const bool isInt = MathLib::isInt(number);
|
(MathLib::isFloat(number) && MathLib::toDoubleNumber(number) <= 0.))
|
||||||
const bool isFloat = MathLib::isFloat(number);
|
mathfunctionCallWarning(tok);
|
||||||
if (isNegative && isInt && MathLib::toLongNumber(number) <= 0) {
|
}
|
||||||
mathfunctionCallWarning(tok); // case log(-2)
|
else if (Token::Match(tok, "log1p|log1pf|log1pl ( %num% )")) {
|
||||||
} else if (isNegative && isFloat && MathLib::toDoubleNumber(number) <= 0.) {
|
const std::string& number = tok->strAt(2);
|
||||||
mathfunctionCallWarning(tok); // case log(-2.0)
|
if ((MathLib::isInt(number) && MathLib::toLongNumber(number) <= -1) ||
|
||||||
} else if (!isNegative && isFloat && MathLib::toDoubleNumber(number) <= 0.) {
|
(MathLib::isFloat(number) && MathLib::toDoubleNumber(number) <= -1.))
|
||||||
mathfunctionCallWarning(tok); // case log(0.0)
|
mathfunctionCallWarning(tok);
|
||||||
} else if (!isNegative && isInt && MathLib::toLongNumber(number) <= 0) {
|
|
||||||
mathfunctionCallWarning(tok); // case log(0)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// atan2 ( x , y): x and y can not be zero, because this is mathematically not defined
|
// 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% )")) {
|
else if (Token::Match(tok, "atan2|atan2f|atan2l ( %num% , %num% )")) {
|
||||||
|
|
|
@ -478,71 +478,197 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void mathfunctionCall_log() {
|
void mathfunctionCall_log() {
|
||||||
// log,log10,logf,logl,log10f,log10l
|
// log,log10,logf,logl,log10f,log10l,log2,log2f,log2l,log1p,log1pf,log1pl
|
||||||
check("void foo()\n"
|
check("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" std::cout << log(-2) << std::endl;\n"
|
" std::cout << log(-2) << std::endl;\n"
|
||||||
" std::cout << logf(-2) << std::endl;\n"
|
" std::cout << logf(-2) << std::endl;\n"
|
||||||
" std::cout << logl(-2) << std::endl;\n"
|
" std::cout << logl(-2) << std::endl;\n"
|
||||||
|
" std::cout << log10(-2) << std::endl;\n"
|
||||||
|
" std::cout << log10f(-2) << std::endl;\n"
|
||||||
|
" std::cout << log10l(-2) << std::endl;\n"
|
||||||
|
" std::cout << log2(-2) << std::endl;\n"
|
||||||
|
" std::cout << log2f(-2) << std::endl;\n"
|
||||||
|
" std::cout << log2l(-2) << std::endl;\n"
|
||||||
|
" std::cout << log1p(-3) << std::endl;\n"
|
||||||
|
" std::cout << log1pf(-3) << std::endl;\n"
|
||||||
|
" std::cout << log1pl(-3) << std::endl;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (warning) Passing value -2 to log() leads to implementation-defined result.\n"
|
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: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());
|
"[test.cpp:5]: (warning) Passing value -2 to logl() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:6]: (warning) Passing value -2 to log10() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:7]: (warning) Passing value -2 to log10f() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:8]: (warning) Passing value -2 to log10l() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:9]: (warning) Passing value -2 to log2() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:10]: (warning) Passing value -2 to log2f() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:11]: (warning) Passing value -2 to log2l() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:12]: (warning) Passing value -3 to log1p() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:13]: (warning) Passing value -3 to log1pf() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:14]: (warning) Passing value -3 to log1pl() leads to implementation-defined result.\n", errout.str());
|
||||||
|
|
||||||
check("void foo()\n"
|
check("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" std::cout << log(-1) << std::endl;\n"
|
" std::cout << log(-1) << std::endl;\n"
|
||||||
" std::cout << logf(-1) << std::endl;\n"
|
" std::cout << logf(-1) << std::endl;\n"
|
||||||
" std::cout << logl(-1) << std::endl;\n"
|
" std::cout << logl(-1) << std::endl;\n"
|
||||||
|
" std::cout << log10(-1) << std::endl;\n"
|
||||||
|
" std::cout << log10f(-1) << std::endl;\n"
|
||||||
|
" std::cout << log10l(-1) << std::endl;\n"
|
||||||
|
" std::cout << log2(-1) << std::endl;\n"
|
||||||
|
" std::cout << log2f(-1) << std::endl;\n"
|
||||||
|
" std::cout << log2l(-1) << std::endl;\n"
|
||||||
|
" std::cout << log1p(-2) << std::endl;\n"
|
||||||
|
" std::cout << log1pf(-2) << std::endl;\n"
|
||||||
|
" std::cout << log1pl(-2) << std::endl;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (warning) Passing value -1 to log() leads to implementation-defined result.\n"
|
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: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());
|
"[test.cpp:5]: (warning) Passing value -1 to logl() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:6]: (warning) Passing value -1 to log10() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:7]: (warning) Passing value -1 to log10f() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:8]: (warning) Passing value -1 to log10l() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:9]: (warning) Passing value -1 to log2() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:10]: (warning) Passing value -1 to log2f() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:11]: (warning) Passing value -1 to log2l() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:12]: (warning) Passing value -2 to log1p() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:13]: (warning) Passing value -2 to log1pf() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:14]: (warning) Passing value -2 to log1pl() leads to implementation-defined result.\n", errout.str());
|
||||||
|
|
||||||
check("void foo()\n"
|
check("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" std::cout << log(-1.0) << std::endl;\n"
|
" std::cout << log(-1.0) << std::endl;\n"
|
||||||
" std::cout << logf(-1.0) << std::endl;\n"
|
" std::cout << logf(-1.0) << std::endl;\n"
|
||||||
" std::cout << logl(-1.0) << std::endl;\n"
|
" std::cout << logl(-1.0) << std::endl;\n"
|
||||||
|
" std::cout << log10(-1.0) << std::endl;\n"
|
||||||
|
" std::cout << log10f(-1.0) << std::endl;\n"
|
||||||
|
" std::cout << log10l(-1.0) << std::endl;\n"
|
||||||
|
" std::cout << log2(-1.0) << std::endl;\n"
|
||||||
|
" std::cout << log2f(-1.0) << std::endl;\n"
|
||||||
|
" std::cout << log2l(-1.0) << std::endl;\n"
|
||||||
|
" std::cout << log1p(-2.0) << std::endl;\n"
|
||||||
|
" std::cout << log1pf(-2.0) << std::endl;\n"
|
||||||
|
" std::cout << log1pl(-2.0) << std::endl;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (warning) Passing value -1.0 to log() leads to implementation-defined result.\n"
|
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: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());
|
"[test.cpp:5]: (warning) Passing value -1.0 to logl() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:6]: (warning) Passing value -1.0 to log10() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:7]: (warning) Passing value -1.0 to log10f() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:8]: (warning) Passing value -1.0 to log10l() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:9]: (warning) Passing value -1.0 to log2() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:10]: (warning) Passing value -1.0 to log2f() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:11]: (warning) Passing value -1.0 to log2l() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:12]: (warning) Passing value -2.0 to log1p() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:13]: (warning) Passing value -2.0 to log1pf() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:14]: (warning) Passing value -2.0 to log1pl() leads to implementation-defined result.\n", errout.str());
|
||||||
|
|
||||||
check("void foo()\n"
|
check("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" std::cout << log(-0.1) << std::endl;\n"
|
" std::cout << log(-0.1) << std::endl;\n"
|
||||||
" std::cout << logf(-0.1) << std::endl;\n"
|
" std::cout << logf(-0.1) << std::endl;\n"
|
||||||
" std::cout << logl(-0.1) << std::endl;\n"
|
" std::cout << logl(-0.1) << std::endl;\n"
|
||||||
|
" std::cout << log10(-0.1) << std::endl;\n"
|
||||||
|
" std::cout << log10f(-0.1) << std::endl;\n"
|
||||||
|
" std::cout << log10l(-0.1) << std::endl;\n"
|
||||||
|
" std::cout << log2(-0.1) << std::endl;\n"
|
||||||
|
" std::cout << log2f(-0.1) << std::endl;\n"
|
||||||
|
" std::cout << log2l(-0.1) << std::endl;\n"
|
||||||
|
" std::cout << log1p(-1.1) << std::endl;\n"
|
||||||
|
" std::cout << log1pf(-1.1) << std::endl;\n"
|
||||||
|
" std::cout << log1pl(-1.1) << std::endl;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (warning) Passing value -0.1 to log() leads to implementation-defined result.\n"
|
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: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());
|
"[test.cpp:5]: (warning) Passing value -0.1 to logl() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:6]: (warning) Passing value -0.1 to log10() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:7]: (warning) Passing value -0.1 to log10f() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:8]: (warning) Passing value -0.1 to log10l() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:9]: (warning) Passing value -0.1 to log2() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:10]: (warning) Passing value -0.1 to log2f() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:11]: (warning) Passing value -0.1 to log2l() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:12]: (warning) Passing value -1.1 to log1p() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:13]: (warning) Passing value -1.1 to log1pf() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:14]: (warning) Passing value -1.1 to log1pl() leads to implementation-defined result.\n", errout.str());
|
||||||
|
|
||||||
check("void foo()\n"
|
check("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" std::cout << log(0) << std::endl;\n"
|
" std::cout << log(0) << std::endl;\n"
|
||||||
" std::cout << logf(0.) << std::endl;\n"
|
" std::cout << logf(0.) << std::endl;\n"
|
||||||
" std::cout << logl(0.0) << std::endl;\n"
|
" std::cout << logl(0.0) << std::endl;\n"
|
||||||
|
" std::cout << log10(0.0) << std::endl;\n"
|
||||||
|
" std::cout << log10f(0) << std::endl;\n"
|
||||||
|
" std::cout << log10l(0.) << std::endl;\n"
|
||||||
|
" std::cout << log2(0.) << std::endl;\n"
|
||||||
|
" std::cout << log2f(0.0) << std::endl;\n"
|
||||||
|
" std::cout << log2l(0) << std::endl;\n"
|
||||||
|
" std::cout << log1p(-1.) << std::endl;\n"
|
||||||
|
" std::cout << log1pf(-1.0) << std::endl;\n"
|
||||||
|
" std::cout << log1pl(-1) << std::endl;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (warning) Passing value 0 to log() leads to implementation-defined result.\n"
|
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: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());
|
"[test.cpp:5]: (warning) Passing value 0.0 to logl() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:6]: (warning) Passing value 0.0 to log10() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:7]: (warning) Passing value 0 to log10f() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:8]: (warning) Passing value 0. to log10l() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:9]: (warning) Passing value 0. to log2() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:10]: (warning) Passing value 0.0 to log2f() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:11]: (warning) Passing value 0 to log2l() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:12]: (warning) Passing value -1. to log1p() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:13]: (warning) Passing value -1.0 to log1pf() leads to implementation-defined result.\n"
|
||||||
|
"[test.cpp:14]: (warning) Passing value -1 to log1pl() leads to implementation-defined result.\n", errout.str());
|
||||||
|
|
||||||
check("void foo()\n"
|
check("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" std::cout << log(1E-3) << std::endl;\n"
|
" std::cout << log(1E-3) << std::endl;\n"
|
||||||
" std::cout << logf(1E-3) << std::endl;\n"
|
" std::cout << logf(1E-3) << std::endl;\n"
|
||||||
" std::cout << logl(1E-3) << std::endl;\n"
|
" std::cout << logl(1E-3) << std::endl;\n"
|
||||||
" std::cout << log(1.0E-3) << std::endl;\n"
|
" std::cout << log10(1E-3) << std::endl;\n"
|
||||||
" std::cout << logf(1.0E-3) << std::endl;\n"
|
" std::cout << log10f(1E-3) << std::endl;\n"
|
||||||
" std::cout << logl(1.0E-3) << std::endl;\n"
|
" std::cout << log10l(1E-3) << std::endl;\n"
|
||||||
" std::cout << log(1.0E+3) << std::endl;\n"
|
" std::cout << log2(1E-3) << std::endl;\n"
|
||||||
" std::cout << logf(1.0E+3) << std::endl;\n"
|
" std::cout << log2f(1E-3) << std::endl;\n"
|
||||||
" std::cout << logl(1.0E+3) << std::endl;\n"
|
" std::cout << log2l(1E-3) << std::endl;\n"
|
||||||
" std::cout << log(2.0) << std::endl;\n"
|
" std::cout << log1p(-1+1E-3) << std::endl;\n"
|
||||||
" std::cout << logf(2.0) << std::endl;\n"
|
" std::cout << log1pf(-1+1E-3) << std::endl;\n"
|
||||||
" std::cout << logf(2.0f) << std::endl;\n"
|
" std::cout << log1pl(-1+1E-3) << std::endl;\n"
|
||||||
|
" std::cout << log(1.0E-3) << std::endl;\n"
|
||||||
|
" std::cout << logf(1.0E-3) << std::endl;\n"
|
||||||
|
" std::cout << logl(1.0E-3) << std::endl;\n"
|
||||||
|
" std::cout << log10(1.0E-3) << std::endl;\n"
|
||||||
|
" std::cout << log10f(1.0E-3) << std::endl;\n"
|
||||||
|
" std::cout << log10l(1.0E-3) << std::endl;\n"
|
||||||
|
" std::cout << log2(1.0E-3) << std::endl;\n"
|
||||||
|
" std::cout << log2f(1.0E-3) << std::endl;\n"
|
||||||
|
" std::cout << log2l(1.0E-3) << std::endl;\n"
|
||||||
|
" std::cout << log1p(-1+1.0E-3) << std::endl;\n"
|
||||||
|
" std::cout << log1pf(-1+1.0E-3) << std::endl;\n"
|
||||||
|
" std::cout << log1pl(-1+1.0E-3) << std::endl;\n"
|
||||||
|
" std::cout << log(1.0E+3) << std::endl;\n"
|
||||||
|
" std::cout << logf(1.0E+3) << std::endl;\n"
|
||||||
|
" std::cout << logl(1.0E+3) << std::endl;\n"
|
||||||
|
" std::cout << log10(1.0E+3) << std::endl;\n"
|
||||||
|
" std::cout << log10f(1.0E+3) << std::endl;\n"
|
||||||
|
" std::cout << log10l(1.0E+3) << std::endl;\n"
|
||||||
|
" std::cout << log2(1.0E+3) << std::endl;\n"
|
||||||
|
" std::cout << log2f(1.0E+3) << std::endl;\n"
|
||||||
|
" std::cout << log2l(1.0E+3) << std::endl;\n"
|
||||||
|
" std::cout << log1p(1.0E+3) << std::endl;\n"
|
||||||
|
" std::cout << log1pf(1.0E+3) << std::endl;\n"
|
||||||
|
" std::cout << log1pl(1.0E+3) << std::endl;\n"
|
||||||
|
" std::cout << log(2.0) << std::endl;\n"
|
||||||
|
" std::cout << logf(2.0) << std::endl;\n"
|
||||||
|
" std::cout << logf(2.0f) << std::endl;\n"
|
||||||
|
" std::cout << log10(2.0) << std::endl;\n"
|
||||||
|
" std::cout << log10f(2.0) << std::endl;\n"
|
||||||
|
" std::cout << log10f(2.0f) << std::endl;\n"
|
||||||
|
" std::cout << log2(2.0) << std::endl;\n"
|
||||||
|
" std::cout << log2f(2.0) << std::endl;\n"
|
||||||
|
" std::cout << log2f(2.0f) << std::endl;\n"
|
||||||
|
" std::cout << log1p(2.0) << std::endl;\n"
|
||||||
|
" std::cout << log1pf(2.0) << std::endl;\n"
|
||||||
|
" std::cout << log1pf(2.0f) << std::endl;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue