Fix false positive with several ! (not) operators (#1856)

With the following code
  int f(int x, int y) {
      if (!!(x != 0)) {
        return y/x;
  }

cppcheck would wrongly warn that there might be a division by zero in
"return y/x;".
This commit is contained in:
Ken-Patrick 2019-05-29 09:45:15 +02:00 committed by Daniel Marjamäki
parent 1e7f5010eb
commit 3cdc236e10
2 changed files with 42 additions and 6 deletions

View File

@ -3749,12 +3749,16 @@ struct ValueFlowConditionHandler {
// if astParent is "!" we need to invert codeblock
{
const Token *parent = tok->astParent();
while (parent && parent->str() == "&&")
parent = parent->astParent();
if (parent && (parent->str() == "!" || Token::simpleMatch(parent, "== false"))) {
check_if = !check_if;
check_else = !check_else;
const Token *tok2 = tok;
while(tok2->astParent()){
const Token *parent = tok2->astParent();
while (parent && parent->str() == "&&")
parent = parent->astParent();
if (parent && (parent->str() == "!" || Token::simpleMatch(parent, "== false"))) {
check_if = !check_if;
check_else = !check_else;
}
tok2 = parent;
}
}

View File

@ -81,6 +81,7 @@ private:
TEST_CASE(valueFlowAfterAssign);
TEST_CASE(valueFlowAfterCondition);
TEST_CASE(valueFlowAfterConditionSeveralNot);
TEST_CASE(valueFlowForwardCompoundAssign);
TEST_CASE(valueFlowForwardCorrelatedVariables);
TEST_CASE(valueFlowForwardModifiedVariables);
@ -2244,6 +2245,37 @@ private:
ASSERT_EQUALS(false, testValueOfX(code, 6U, 0));
}
void valueFlowAfterConditionSeveralNot() {
const char *code;
code = "int f(int x, int y) {\n"
" if (x!=0) {}\n"
" return y/x;\n"
"}";
ASSERT_EQUALS(true, testValueOfX(code, 3U, 0));
code = "int f(int x, int y) {\n"
" if (!!(x != 0)) {\n"
" return y/x;\n"
"}\n"
"}";
ASSERT_EQUALS(false, testValueOfX(code, 3U, 0));
code = "int f(int x, int y) {\n"
" if (!!!(x != 0)) {\n"
" return y/x;\n"
"}\n"
"}";
ASSERT_EQUALS(true, testValueOfX(code, 3U, 0));
code = "int f(int x, int y) {\n"
" if (!!!!(x != 0)) {\n"
" return y/x;\n"
"}\n"
"}";
ASSERT_EQUALS(false, testValueOfX(code, 3U, 0));
}
void valueFlowForwardCompoundAssign() {
const char *code;