Improved checking for opposite conditions

This commit is contained in:
Daniel Marjamäki 2017-08-31 22:53:21 +02:00
parent 8b509a158f
commit 7fad1b9a36
2 changed files with 124 additions and 2 deletions

View File

@ -281,8 +281,15 @@ bool isOppositeCond(bool isNot, bool cpp, const Token * const cond1, const Token
cond2->astOperand2() && cond2->astOperand2()->hasKnownIntValue()) {
const ValueFlow::Value &rhsValue1 = cond1->astOperand2()->values().front();
const ValueFlow::Value &rhsValue2 = cond2->astOperand2()->values().front();
if (comp1 == "<" && cond2->str() == "==")
return (rhsValue1.intvalue < rhsValue2.intvalue);
bool secondAlwaysFalse = false;
if (comp1 == "<" || comp1 == "<=")
secondAlwaysFalse = Token::Match(cond2, "==|>|>=") && (rhsValue1.intvalue < rhsValue2.intvalue);
else if (comp1 == ">=" || comp1 == ">")
secondAlwaysFalse = Token::Match(cond2, "==|<|<=") && (rhsValue1.intvalue > rhsValue2.intvalue);
if (secondAlwaysFalse)
return true;
}
}

View File

@ -76,6 +76,7 @@ private:
TEST_CASE(modulo);
TEST_CASE(oppositeInnerCondition);
TEST_CASE(oppositeInnerCondition2);
TEST_CASE(clarifyCondition1); // if (a = b() < 0)
TEST_CASE(clarifyCondition2); // if (a & b == c)
@ -1584,6 +1585,120 @@ private:
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Opposite conditions in nested 'if' blocks lead to a dead code block.\n", errout.str());
}
void oppositeInnerCondition2() {
// first comparison: <
check("void f(int x) {\n"
"\n"
" if (x<4) {\n"
" if (x==5) {}\n" // <- Warning
" }\n"
"\n"
" if (x<4) {\n"
" if (x!=5) {}\n" // <- TODO
" }\n"
"\n"
" if (x<4) {\n"
" if (x>5) {}\n" // <- Warning
" }\n"
"\n"
" if (x<4) {\n"
" if (x>=5) {}\n" // <- Warning
" }\n"
"\n"
" if (x<4) {\n"
" if (x<5) {}\n"
" }\n"
"\n"
" if (x<4) {\n"
" if (x<=5) {}\n"
" }\n"
"}");
ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (warning) Opposite conditions in nested 'if' blocks lead to a dead code block.\n"
"[test.cpp:11] -> [test.cpp:12]: (warning) Opposite conditions in nested 'if' blocks lead to a dead code block.\n"
"[test.cpp:15] -> [test.cpp:16]: (warning) Opposite conditions in nested 'if' blocks lead to a dead code block.\n"
, errout.str());
check("void f(int x) {\n"
"\n"
" if (x<5) {\n"
" if (x==4) {}\n"
" }\n"
"\n"
" if (x<5) {\n"
" if (x!=4) {}\n"
" }\n"
"\n"
" if (x<5) {\n"
" if (x>4) {}\n" // <- TODO
" }\n"
"\n"
" if (x<5) {\n"
" if (x>=4) {}\n"
" }\n"
"\n"
" if (x<5) {\n"
" if (x<4) {}\n"
" }\n"
"\n"
" if (x<5) {\n"
" if (x<=4) {}\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
// first comparison: >
check("void f(int x) {\n"
"\n"
" if (x>4) {\n"
" if (x==5) {}\n"
" }\n"
"\n"
" if (x>4) {\n"
" if (x>5) {}\n"
" }\n"
"\n"
" if (x>4) {\n"
" if (x>=5) {}\n" // <- TODO
" }\n"
"\n"
" if (x>4) {\n"
" if (x<5) {}\n" // <- TODO
" }\n"
"\n"
" if (x>4) {\n"
" if (x<=5) {}\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
check("void f(int x) {\n"
"\n"
" if (x>5) {\n"
" if (x==4) {}\n" // <- Warning
" }\n"
"\n"
" if (x>5) {\n"
" if (x>4) {}\n" // <- TODO
" }\n"
"\n"
" if (x>5) {\n"
" if (x>=4) {}\n" // <- TODO
" }\n"
"\n"
" if (x>5) {\n"
" if (x<4) {}\n" // <- Warning
" }\n"
"\n"
" if (x>5) {\n"
" if (x<=4) {}\n" // <- Warning
" }\n"
"}");
ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (warning) Opposite conditions in nested 'if' blocks lead to a dead code block.\n"
"[test.cpp:15] -> [test.cpp:16]: (warning) Opposite conditions in nested 'if' blocks lead to a dead code block.\n"
"[test.cpp:19] -> [test.cpp:20]: (warning) Opposite conditions in nested 'if' blocks lead to a dead code block.\n"
, errout.str());
}
// clarify conditions with = and comparison
void clarifyCondition1() {
check("void f() {\n"