Set ValueType for assignment operators, detect division by zero for %= and /= again (#7322)

This commit is contained in:
PKEuS 2016-02-02 17:17:33 +01:00
parent 64977bb37b
commit 841f17776b
3 changed files with 29 additions and 4 deletions

View File

@ -1609,7 +1609,9 @@ void CheckOther::checkZeroDivision()
const bool printInconclusive = _settings->inconclusive;
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
if (!Token::Match(tok, "[/%]") || !tok->astOperand1() || !tok->astOperand2())
if (!tok->astOperand2() || !tok->astOperand1())
continue;
if (tok->str() != "%" && tok->str() != "/" && tok->str() != "%=" && tok->str() != "/=")
continue;
if (!tok->valueType() || !tok->valueType()->isIntegral())
continue;
@ -1619,9 +1621,9 @@ void CheckOther::checkZeroDivision()
} else if (tok->astOperand1()->isName()) {
if (tok->astOperand1()->variable() && !tok->astOperand1()->variable()->isIntegralType())
continue;
} else if (!tok->astOperand1()->isArithmeticalOp()) {
} else if (!tok->astOperand1()->isArithmeticalOp())
continue;
}
// Value flow..
const ValueFlow::Value *value = tok->astOperand2()->getValue(0LL);
if (!value)

View File

@ -3720,7 +3720,7 @@ static void setValueType(Token *tok, const ValueType &valuetype, bool cpp, Value
if (vt2 &&
vt1->isIntegral() && vt1->pointer == 0U &&
vt2->isIntegral() && vt2->pointer == 0U &&
(parent->isArithmeticalOp() ||parent->tokType() == Token::eBitOp)) {
(parent->isArithmeticalOp() || parent->tokType() == Token::eBitOp || parent->isAssignmentOp())) {
ValueType vt;
if (vt1->type == vt2->type) {

View File

@ -36,6 +36,7 @@ private:
TEST_CASE(zeroDiv1);
TEST_CASE(zeroDiv2);
TEST_CASE(zeroDiv3);
TEST_CASE(zeroDiv4);
TEST_CASE(zeroDiv5);
TEST_CASE(zeroDiv6);
@ -293,6 +294,28 @@ private:
ASSERT_EQUALS("", errout.str());
}
void zeroDiv3() {
check("int foo(int i) {\n"
" return i / 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (error) Division by zero.\n", errout.str());
check("int foo(int i) {\n"
" return i % 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (error) Division by zero.\n", errout.str());
check("void foo(int& i) {\n"
" i /= 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (error) Division by zero.\n", errout.str());
check("void foo(int& i) {\n"
" i %= 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (error) Division by zero.\n", errout.str());
}
void zeroDiv4() {
check("void f()\n"
"{\n"