Fix issue 7324: valueFlowForward : decrement (#2737)

This commit is contained in:
Paul Fultz II 2020-08-24 06:10:36 -05:00 committed by GitHub
parent c5369b84e1
commit 02287d9d34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 2 deletions

View File

@ -211,6 +211,8 @@ struct ForwardTraversal {
Progress updateLoop(Token* endBlock, Token* condTok, Token* initTok = nullptr, Token* stepTok = nullptr) {
ForwardAnalyzer::Action bodyAnalysis = analyzeScope(endBlock);
ForwardAnalyzer::Action allAnalysis = bodyAnalysis;
if (condTok)
allAnalysis |= analyzeRecursive(condTok);
if (initTok)
allAnalysis |= analyzeRecursive(initTok);
if (stepTok)
@ -422,8 +424,12 @@ struct ForwardTraversal {
tok = endBlock;
} else if (Token::simpleMatch(tok, "do {")) {
Token* endBlock = tok->next()->link();
if (updateLoop(endBlock, nullptr) == Progress::Break)
Token* condTok = Token::simpleMatch(endBlock, "} while (") ? endBlock->tokAt(2)->astOperand2() : nullptr;
if (updateLoop(endBlock, condTok) == Progress::Break)
return Progress::Break;
if (condTok)
tok = endBlock->linkAt(2)->next();
else
tok = endBlock;
} else if (Token::Match(tok, "assert|ASSERT (")) {
const Token* condTok = tok->next()->astOperand2();

View File

@ -790,6 +790,38 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
}
}
// increment
else if (parent->str() == "++") {
for (const ValueFlow::Value &val : tok->values()) {
if (!val.isIntValue() && !val.isFloatValue())
continue;
ValueFlow::Value v(val);
if (parent == tok->previous()) {
if (v.isIntValue())
v.intvalue = v.intvalue + 1;
else
v.floatValue = v.floatValue + 1.0;
}
setTokenValue(parent, v, settings);
}
}
// decrement
else if (parent->str() == "--") {
for (const ValueFlow::Value &val : tok->values()) {
if (!val.isIntValue() && !val.isFloatValue())
continue;
ValueFlow::Value v(val);
if (parent == tok->previous()) {
if (v.isIntValue())
v.intvalue = v.intvalue - 1;
else
v.floatValue = v.floatValue - 1.0;
}
setTokenValue(parent, v, settings);
}
}
// Array element
else if (parent->str() == "[" && parent->isBinaryOp()) {
for (const ValueFlow::Value &value1 : parent->astOperand1()->values()) {

View File

@ -57,6 +57,7 @@ private:
TEST_CASE(zeroDiv10);
TEST_CASE(zeroDiv11);
TEST_CASE(zeroDiv12);
TEST_CASE(zeroDiv13);
TEST_CASE(zeroDivCond); // division by zero / useless condition
@ -560,6 +561,16 @@ private:
"}\n");
ASSERT_EQUALS("[test.cpp:2]: (error) Division by zero.\n", errout.str());
}
void zeroDiv13() {
// #7324
check("int f () {\n"
" int dividend = 10;\n"
" int divisor = 1;\n"
" dividend = dividend / (--divisor);\n"
" return dividend;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Division by zero.\n", errout.str());
}
void zeroDivCond() {
check("void f(unsigned int x) {\n"