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) { 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;

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 // 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()) {

View File

@ -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"