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:
parent
1e7f5010eb
commit
3cdc236e10
|
@ -3749,12 +3749,16 @@ struct ValueFlowConditionHandler {
|
||||||
|
|
||||||
// if astParent is "!" we need to invert codeblock
|
// if astParent is "!" we need to invert codeblock
|
||||||
{
|
{
|
||||||
const Token *parent = tok->astParent();
|
const Token *tok2 = tok;
|
||||||
while (parent && parent->str() == "&&")
|
while(tok2->astParent()){
|
||||||
parent = parent->astParent();
|
const Token *parent = tok2->astParent();
|
||||||
if (parent && (parent->str() == "!" || Token::simpleMatch(parent, "== false"))) {
|
while (parent && parent->str() == "&&")
|
||||||
check_if = !check_if;
|
parent = parent->astParent();
|
||||||
check_else = !check_else;
|
if (parent && (parent->str() == "!" || Token::simpleMatch(parent, "== false"))) {
|
||||||
|
check_if = !check_if;
|
||||||
|
check_else = !check_else;
|
||||||
|
}
|
||||||
|
tok2 = parent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,7 @@ private:
|
||||||
|
|
||||||
TEST_CASE(valueFlowAfterAssign);
|
TEST_CASE(valueFlowAfterAssign);
|
||||||
TEST_CASE(valueFlowAfterCondition);
|
TEST_CASE(valueFlowAfterCondition);
|
||||||
|
TEST_CASE(valueFlowAfterConditionSeveralNot);
|
||||||
TEST_CASE(valueFlowForwardCompoundAssign);
|
TEST_CASE(valueFlowForwardCompoundAssign);
|
||||||
TEST_CASE(valueFlowForwardCorrelatedVariables);
|
TEST_CASE(valueFlowForwardCorrelatedVariables);
|
||||||
TEST_CASE(valueFlowForwardModifiedVariables);
|
TEST_CASE(valueFlowForwardModifiedVariables);
|
||||||
|
@ -2244,6 +2245,37 @@ private:
|
||||||
ASSERT_EQUALS(false, testValueOfX(code, 6U, 0));
|
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() {
|
void valueFlowForwardCompoundAssign() {
|
||||||
const char *code;
|
const char *code;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue