Fix issue 7324: valueFlowForward : decrement (#2737)
This commit is contained in:
parent
c5369b84e1
commit
02287d9d34
|
@ -211,6 +211,8 @@ struct ForwardTraversal {
|
||||||
Progress updateLoop(Token* endBlock, Token* condTok, Token* initTok = nullptr, Token* stepTok = nullptr) {
|
Progress updateLoop(Token* endBlock, Token* condTok, Token* initTok = nullptr, Token* stepTok = nullptr) {
|
||||||
ForwardAnalyzer::Action bodyAnalysis = analyzeScope(endBlock);
|
ForwardAnalyzer::Action bodyAnalysis = analyzeScope(endBlock);
|
||||||
ForwardAnalyzer::Action allAnalysis = bodyAnalysis;
|
ForwardAnalyzer::Action allAnalysis = bodyAnalysis;
|
||||||
|
if (condTok)
|
||||||
|
allAnalysis |= analyzeRecursive(condTok);
|
||||||
if (initTok)
|
if (initTok)
|
||||||
allAnalysis |= analyzeRecursive(initTok);
|
allAnalysis |= analyzeRecursive(initTok);
|
||||||
if (stepTok)
|
if (stepTok)
|
||||||
|
@ -422,9 +424,13 @@ struct ForwardTraversal {
|
||||||
tok = endBlock;
|
tok = endBlock;
|
||||||
} else if (Token::simpleMatch(tok, "do {")) {
|
} else if (Token::simpleMatch(tok, "do {")) {
|
||||||
Token* endBlock = tok->next()->link();
|
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;
|
return Progress::Break;
|
||||||
tok = endBlock;
|
if (condTok)
|
||||||
|
tok = endBlock->linkAt(2)->next();
|
||||||
|
else
|
||||||
|
tok = endBlock;
|
||||||
} else if (Token::Match(tok, "assert|ASSERT (")) {
|
} else if (Token::Match(tok, "assert|ASSERT (")) {
|
||||||
const Token* condTok = tok->next()->astOperand2();
|
const Token* condTok = tok->next()->astOperand2();
|
||||||
bool checkThen, checkElse;
|
bool checkThen, checkElse;
|
||||||
|
|
|
@ -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
|
// Array element
|
||||||
else if (parent->str() == "[" && parent->isBinaryOp()) {
|
else if (parent->str() == "[" && parent->isBinaryOp()) {
|
||||||
for (const ValueFlow::Value &value1 : parent->astOperand1()->values()) {
|
for (const ValueFlow::Value &value1 : parent->astOperand1()->values()) {
|
||||||
|
|
|
@ -57,6 +57,7 @@ private:
|
||||||
TEST_CASE(zeroDiv10);
|
TEST_CASE(zeroDiv10);
|
||||||
TEST_CASE(zeroDiv11);
|
TEST_CASE(zeroDiv11);
|
||||||
TEST_CASE(zeroDiv12);
|
TEST_CASE(zeroDiv12);
|
||||||
|
TEST_CASE(zeroDiv13);
|
||||||
|
|
||||||
TEST_CASE(zeroDivCond); // division by zero / useless condition
|
TEST_CASE(zeroDivCond); // division by zero / useless condition
|
||||||
|
|
||||||
|
@ -560,6 +561,16 @@ private:
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (error) Division by zero.\n", errout.str());
|
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() {
|
void zeroDivCond() {
|
||||||
check("void f(unsigned int x) {\n"
|
check("void f(unsigned int x) {\n"
|
||||||
|
|
Loading…
Reference in New Issue