Fixed #5584 (FP: Division by zero when function not declared)
This commit is contained in:
parent
b37e9601c1
commit
54e7f34f4a
|
@ -2249,26 +2249,28 @@ void CheckOther::checkZeroDivision()
|
||||||
if (tok->variable() || tok->function())
|
if (tok->variable() || tok->function())
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
zerodivError(tok);
|
zerodivError(tok,false);
|
||||||
} else if (Token::Match(tok, "[/%]") && tok->astOperand2() && !tok->astOperand2()->values.empty()) {
|
} else if (Token::Match(tok, "[/%]") && tok->astOperand2() && !tok->astOperand2()->values.empty()) {
|
||||||
// Value flow..
|
// Value flow..
|
||||||
const ValueFlow::Value *value = tok->astOperand2()->getValue(0LL);
|
const ValueFlow::Value *value = tok->astOperand2()->getValue(0LL);
|
||||||
if (value) {
|
if (value) {
|
||||||
|
if (!_settings->inconclusive && value->inconclusive)
|
||||||
|
continue;
|
||||||
if (value->condition == nullptr)
|
if (value->condition == nullptr)
|
||||||
zerodivError(tok);
|
zerodivError(tok, value->inconclusive);
|
||||||
else if (_settings->isEnabled("warning"))
|
else if (_settings->isEnabled("warning"))
|
||||||
zerodivcondError(value->condition,tok);
|
zerodivcondError(value->condition,tok,value->inconclusive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckOther::zerodivError(const Token *tok)
|
void CheckOther::zerodivError(const Token *tok, bool inconclusive)
|
||||||
{
|
{
|
||||||
reportError(tok, Severity::error, "zerodiv", "Division by zero.");
|
reportError(tok, Severity::error, "zerodiv", "Division by zero.", inconclusive);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckOther::zerodivcondError(const Token *tokcond, const Token *tokdiv)
|
void CheckOther::zerodivcondError(const Token *tokcond, const Token *tokdiv, bool inconclusive)
|
||||||
{
|
{
|
||||||
std::list<const Token *> callstack;
|
std::list<const Token *> callstack;
|
||||||
while (Token::Match(tokcond, "(|%oror%|&&"))
|
while (Token::Match(tokcond, "(|%oror%|&&"))
|
||||||
|
@ -2291,7 +2293,7 @@ void CheckOther::zerodivcondError(const Token *tokcond, const Token *tokdiv)
|
||||||
condition = tokcond->str() + "!=0";
|
condition = tokcond->str() + "!=0";
|
||||||
}
|
}
|
||||||
const std::string linenr(MathLib::toString(tokdiv ? tokdiv->linenr() : 0));
|
const std::string linenr(MathLib::toString(tokdiv ? tokdiv->linenr() : 0));
|
||||||
reportError(callstack, Severity::warning, "zerodivcond", "Either the condition '"+condition+"' is useless or there is division by zero at line " + linenr + ".");
|
reportError(callstack, Severity::warning, "zerodivcond", "Either the condition '"+condition+"' is useless or there is division by zero at line " + linenr + ".", inconclusive);
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
|
@ -290,8 +290,8 @@ private:
|
||||||
void charBitOpError(const Token *tok);
|
void charBitOpError(const Token *tok);
|
||||||
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, bool inconclusive);
|
||||||
void zerodivcondError(const Token *tokcond, const Token *tokdiv);
|
void zerodivcondError(const Token *tokcond, const Token *tokdiv, bool inconclusive);
|
||||||
void nanInArithmeticExpressionError(const Token *tok);
|
void nanInArithmeticExpressionError(const Token *tok);
|
||||||
void mathfunctionCallError(const Token *tok, const unsigned int numParam = 1);
|
void mathfunctionCallError(const Token *tok, const unsigned int numParam = 1);
|
||||||
void redundantAssignmentError(const Token *tok1, const Token* tok2, const std::string& var, bool inconclusive);
|
void redundantAssignmentError(const Token *tok1, const Token* tok2, const std::string& var, bool inconclusive);
|
||||||
|
@ -340,8 +340,8 @@ private:
|
||||||
c.invalidFunctionArgError(0, "func_name", 1, "1-4");
|
c.invalidFunctionArgError(0, "func_name", 1, "1-4");
|
||||||
c.invalidFunctionArgBoolError(0, "func_name", 1);
|
c.invalidFunctionArgBoolError(0, "func_name", 1);
|
||||||
c.udivError(0, false);
|
c.udivError(0, false);
|
||||||
c.zerodivError(0);
|
c.zerodivError(0, false);
|
||||||
c.zerodivcondError(0,0);
|
c.zerodivcondError(0,0,false);
|
||||||
c.mathfunctionCallError(0);
|
c.mathfunctionCallError(0);
|
||||||
c.misusedScopeObjectError(NULL, "varname");
|
c.misusedScopeObjectError(NULL, "varname");
|
||||||
c.doubleFreeError(0, "varname");
|
c.doubleFreeError(0, "varname");
|
||||||
|
|
|
@ -45,6 +45,7 @@ private:
|
||||||
TEST_CASE(zeroDiv5);
|
TEST_CASE(zeroDiv5);
|
||||||
TEST_CASE(zeroDiv6);
|
TEST_CASE(zeroDiv6);
|
||||||
TEST_CASE(zeroDiv7); // #4930
|
TEST_CASE(zeroDiv7); // #4930
|
||||||
|
TEST_CASE(zeroDiv8);
|
||||||
|
|
||||||
TEST_CASE(zeroDivCond); // division by zero / useless condition
|
TEST_CASE(zeroDivCond); // division by zero / useless condition
|
||||||
|
|
||||||
|
@ -463,6 +464,16 @@ private:
|
||||||
"[test.cpp:3]: (error) Division by zero.\n", errout.str());
|
"[test.cpp:3]: (error) Division by zero.\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void zeroDiv8() {
|
||||||
|
// #5584 - FP when function is unknown
|
||||||
|
check("void f() {\n"
|
||||||
|
" int a = 0;\n"
|
||||||
|
" do_something(a);\n"
|
||||||
|
" return 4 / a;\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:4]: (error, inconclusive) Division by zero.\n", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void zeroDivCond() {
|
void zeroDivCond() {
|
||||||
check("void f(unsigned int x) {\n"
|
check("void f(unsigned int x) {\n"
|
||||||
" int y = 17 / x;\n"
|
" int y = 17 / x;\n"
|
||||||
|
|
Loading…
Reference in New Issue